diff options
-rw-r--r-- | arch/sparc/mm/tsb.c | 21 | ||||
-rw-r--r-- | kernel/sysctl.c | 14 |
2 files changed, 28 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 | ||
268 | int sysctl_tsb_ratio = -2; | ||
269 | |||
270 | static 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 | ||
312 | retry_tsb_alloc: | 319 | retry_tsb_alloc: |
313 | gfp_flags = GFP_KERNEL; | 320 | gfp_flags = GFP_KERNEL; |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 3d56fe7570da..4e2ac0aec9b0 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -121,6 +121,10 @@ extern int sg_big_buff; | |||
121 | #include <asm/system.h> | 121 | #include <asm/system.h> |
122 | #endif | 122 | #endif |
123 | 123 | ||
124 | #ifdef CONFIG_SPARC64 | ||
125 | extern int sysctl_tsb_ratio; | ||
126 | #endif | ||
127 | |||
124 | #ifdef __hppa__ | 128 | #ifdef __hppa__ |
125 | extern int pwrsw_enabled; | 129 | extern int pwrsw_enabled; |
126 | extern int unaligned_enabled; | 130 | extern int unaligned_enabled; |
@@ -451,6 +455,16 @@ static struct ctl_table kern_table[] = { | |||
451 | .proc_handler = &proc_dointvec, | 455 | .proc_handler = &proc_dointvec, |
452 | }, | 456 | }, |
453 | #endif | 457 | #endif |
458 | #ifdef CONFIG_SPARC64 | ||
459 | { | ||
460 | .ctl_name = CTL_UNNUMBERED, | ||
461 | .procname = "tsb-ratio", | ||
462 | .data = &sysctl_tsb_ratio, | ||
463 | .maxlen = sizeof (int), | ||
464 | .mode = 0644, | ||
465 | .proc_handler = &proc_dointvec, | ||
466 | }, | ||
467 | #endif | ||
454 | #ifdef __hppa__ | 468 | #ifdef __hppa__ |
455 | { | 469 | { |
456 | .ctl_name = KERN_HPPA_PWRSW, | 470 | .ctl_name = KERN_HPPA_PWRSW, |