Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=68dff6a9af9f27df5aeee6d0339818b0e36c1b51
Commit:     68dff6a9af9f27df5aeee6d0339818b0e36c1b51
Parent:     5b95a4acf157eee552e013795b54eaa2ab1ee4a1
Author:     Christoph Lameter <[EMAIL PROTECTED]>
AuthorDate: Tue Jul 17 04:03:20 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Tue Jul 17 10:23:01 2007 -0700

    SLUB slab validation: Move tracking information alloc outside of lock
    
    We currently have to do an GFP_ATOMIC allocation because the list_lock is
    already taken when we first allocate memory for tracking allocation
    information.  It would be better if we could avoid atomic allocations.
    
    Allocate a size of the tracking table that is usually sufficient (one page)
    before we take the list lock.  We will then only do the atomic allocation
    if we need to resize the table to become larger than a page (mostly only
    needed under large NUMA because of the tracking of cpus and nodes otherwise
    the table stays small).
    
    Signed-off-by: Christoph Lameter <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 mm/slub.c |   17 +++++++----------
 1 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/mm/slub.c b/mm/slub.c
index 3c9e98f..a5832f8 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2902,18 +2902,14 @@ static void free_loc_track(struct loc_track *t)
                        get_order(sizeof(struct location) * t->max));
 }
 
-static int alloc_loc_track(struct loc_track *t, unsigned long max)
+static int alloc_loc_track(struct loc_track *t, unsigned long max, gfp_t flags)
 {
        struct location *l;
        int order;
 
-       if (!max)
-               max = PAGE_SIZE / sizeof(struct location);
-
        order = get_order(sizeof(struct location) * max);
 
-       l = (void *)__get_free_pages(GFP_ATOMIC, order);
-
+       l = (void *)__get_free_pages(flags, order);
        if (!l)
                return 0;
 
@@ -2979,7 +2975,7 @@ static int add_location(struct loc_track *t, struct 
kmem_cache *s,
        /*
         * Not found. Insert new tracking element.
         */
-       if (t->count >= t->max && !alloc_loc_track(t, 2 * t->max))
+       if (t->count >= t->max && !alloc_loc_track(t, 2 * t->max, GFP_ATOMIC))
                return 0;
 
        l = t->loc + pos;
@@ -3022,11 +3018,12 @@ static int list_locations(struct kmem_cache *s, char 
*buf,
 {
        int n = 0;
        unsigned long i;
-       struct loc_track t;
+       struct loc_track t = { 0, 0, NULL };
        int node;
 
-       t.count = 0;
-       t.max = 0;
+       if (!alloc_loc_track(&t, PAGE_SIZE / sizeof(struct location),
+                       GFP_KERNEL))
+               return sprintf(buf, "Out of memory\n");
 
        /* Push back cpu slabs */
        flush_all(s);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to