Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 21559
b: refs/heads/master
c: b52439c
h: refs/heads/master
i:
  21557: d95c29d
  21555: ce90183
  21551: f8d5302
v: v3
  • Loading branch information
David S. Miller committed Mar 20, 2006
1 parent da279cf commit 35bae16
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 05f9ca83596c7801549a2b4eba469d51baf5480f
refs/heads/master: b52439c22c63dbbefd5395f2151c0ef4f667e949
43 changes: 35 additions & 8 deletions trunk/arch/sparc64/mm/tsb.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@ static void setup_tsb_params(struct mm_struct *mm, unsigned long tsb_bytes)
*
* The TSB can be anywhere from 8K to 1MB in size, in increasing powers
* of two. The TSB must be aligned to it's size, so f.e. a 512K TSB
* must be 512K aligned.
* must be 512K aligned. It also must be physically contiguous, so we
* cannot use vmalloc().
*
* The idea here is to grow the TSB when the RSS of the process approaches
* the number of entries that the current TSB can hold at once. Currently,
Expand All @@ -228,6 +229,8 @@ void tsb_grow(struct mm_struct *mm, unsigned long rss)
unsigned long size, old_size, flags;
struct page *page;
struct tsb *old_tsb, *new_tsb;
unsigned long order, new_rss_limit;
gfp_t gfp_flags;

if (max_tsb_size > (PAGE_SIZE << MAX_ORDER))
max_tsb_size = (PAGE_SIZE << MAX_ORDER);
Expand All @@ -240,9 +243,37 @@ void tsb_grow(struct mm_struct *mm, unsigned long rss)
break;
}

page = alloc_pages(GFP_KERNEL, get_order(size));
if (unlikely(!page))
if (size == max_tsb_size)
new_rss_limit = ~0UL;
else
new_rss_limit = ((size / sizeof(struct tsb)) * 3) / 4;

retry_page_alloc:
order = get_order(size);
gfp_flags = GFP_KERNEL;
if (order > 1)
gfp_flags = __GFP_NOWARN | __GFP_NORETRY;

page = alloc_pages(gfp_flags, order);
if (unlikely(!page)) {
/* Not being able to fork due to a high-order TSB
* allocation failure is very bad behavior. Just back
* down to a 0-order allocation and force no TSB
* growing for this address space.
*/
if (mm->context.tsb == NULL && order > 0) {
size = PAGE_SIZE;
new_rss_limit = ~0UL;
goto retry_page_alloc;
}

/* If we failed on a TSB grow, we are under serious
* memory pressure so don't try to grow any more.
*/
if (mm->context.tsb != NULL)
mm->context.tsb_rss_limit = ~0UL;
return;
}

/* Mark all tags as invalid. */
new_tsb = page_address(page);
Expand Down Expand Up @@ -286,11 +317,7 @@ void tsb_grow(struct mm_struct *mm, unsigned long rss)
return;
}

if (size == max_tsb_size)
mm->context.tsb_rss_limit = ~0UL;
else
mm->context.tsb_rss_limit =
((size / sizeof(struct tsb)) * 3) / 4;
mm->context.tsb_rss_limit = new_rss_limit;

if (old_tsb) {
extern void copy_tsb(unsigned long old_tsb_base,
Expand Down

0 comments on commit 35bae16

Please sign in to comment.