aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm/tsb.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/mm/tsb.c')
-rw-r--r--arch/sparc/mm/tsb.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c
index f0282fad632a..36a0813f9517 100644
--- a/arch/sparc/mm/tsb.c
+++ b/arch/sparc/mm/tsb.c
@@ -265,6 +265,18 @@ void __init pgtable_cache_init(void)
265 } 265 }
266} 266}
267 267
268int sysctl_tsb_ratio = -2;
269
270static unsigned long tsb_size_to_rss_limit(unsigned long new_size)
271{
272 unsigned long num_ents = (new_size / sizeof(struct tsb));
273
274 if (sysctl_tsb_ratio < 0)
275 return num_ents - (num_ents >> -sysctl_tsb_ratio);
276 else
277 return num_ents + (num_ents >> sysctl_tsb_ratio);
278}
279
268/* When the RSS of an address space exceeds tsb_rss_limit for a TSB, 280/* When the RSS of an address space exceeds tsb_rss_limit for a TSB,
269 * do_sparc64_fault() invokes this routine to try and grow it. 281 * do_sparc64_fault() invokes this routine to try and grow it.
270 * 282 *
@@ -295,19 +307,14 @@ void tsb_grow(struct mm_struct *mm, unsigned long tsb_index, unsigned long rss)
295 307
296 new_cache_index = 0; 308 new_cache_index = 0;
297 for (new_size = 8192; new_size < max_tsb_size; new_size <<= 1UL) { 309 for (new_size = 8192; new_size < max_tsb_size; new_size <<= 1UL) {
298 unsigned long n_entries = new_size / sizeof(struct tsb); 310 new_rss_limit = tsb_size_to_rss_limit(new_size);
299 311 if (new_rss_limit > rss)
300 n_entries = (n_entries * 3) / 4;
301 if (n_entries > rss)
302 break; 312 break;
303
304 new_cache_index++; 313 new_cache_index++;
305 } 314 }
306 315
307 if (new_size == max_tsb_size) 316 if (new_size == max_tsb_size)
308 new_rss_limit = ~0UL; 317 new_rss_limit = ~0UL;
309 else
310 new_rss_limit = ((new_size / sizeof(struct tsb)) * 3) / 4;
311 318
312retry_tsb_alloc: 319retry_tsb_alloc:
313 gfp_flags = GFP_KERNEL; 320 gfp_flags = GFP_KERNEL;