|
@@ -1879,18 +1879,24 @@ redo:
|
|
*/
|
|
*/
|
|
static void unfreeze_partials(struct kmem_cache *s)
|
|
static void unfreeze_partials(struct kmem_cache *s)
|
|
{
|
|
{
|
|
- struct kmem_cache_node *n = NULL;
|
|
|
|
|
|
+ struct kmem_cache_node *n = NULL, *n2 = NULL;
|
|
struct kmem_cache_cpu *c = this_cpu_ptr(s->cpu_slab);
|
|
struct kmem_cache_cpu *c = this_cpu_ptr(s->cpu_slab);
|
|
struct page *page, *discard_page = NULL;
|
|
struct page *page, *discard_page = NULL;
|
|
|
|
|
|
while ((page = c->partial)) {
|
|
while ((page = c->partial)) {
|
|
- enum slab_modes { M_PARTIAL, M_FREE };
|
|
|
|
- enum slab_modes l, m;
|
|
|
|
struct page new;
|
|
struct page new;
|
|
struct page old;
|
|
struct page old;
|
|
|
|
|
|
c->partial = page->next;
|
|
c->partial = page->next;
|
|
- l = M_FREE;
|
|
|
|
|
|
+
|
|
|
|
+ n2 = get_node(s, page_to_nid(page));
|
|
|
|
+ if (n != n2) {
|
|
|
|
+ if (n)
|
|
|
|
+ spin_unlock(&n->list_lock);
|
|
|
|
+
|
|
|
|
+ n = n2;
|
|
|
|
+ spin_lock(&n->list_lock);
|
|
|
|
+ }
|
|
|
|
|
|
do {
|
|
do {
|
|
|
|
|
|
@@ -1903,43 +1909,17 @@ static void unfreeze_partials(struct kmem_cache *s)
|
|
|
|
|
|
new.frozen = 0;
|
|
new.frozen = 0;
|
|
|
|
|
|
- if (!new.inuse && (!n || n->nr_partial > s->min_partial))
|
|
|
|
- m = M_FREE;
|
|
|
|
- else {
|
|
|
|
- struct kmem_cache_node *n2 = get_node(s,
|
|
|
|
- page_to_nid(page));
|
|
|
|
-
|
|
|
|
- m = M_PARTIAL;
|
|
|
|
- if (n != n2) {
|
|
|
|
- if (n)
|
|
|
|
- spin_unlock(&n->list_lock);
|
|
|
|
-
|
|
|
|
- n = n2;
|
|
|
|
- spin_lock(&n->list_lock);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (l != m) {
|
|
|
|
- if (l == M_PARTIAL) {
|
|
|
|
- remove_partial(n, page);
|
|
|
|
- stat(s, FREE_REMOVE_PARTIAL);
|
|
|
|
- } else {
|
|
|
|
- add_partial(n, page,
|
|
|
|
- DEACTIVATE_TO_TAIL);
|
|
|
|
- stat(s, FREE_ADD_PARTIAL);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- l = m;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
} while (!__cmpxchg_double_slab(s, page,
|
|
} while (!__cmpxchg_double_slab(s, page,
|
|
old.freelist, old.counters,
|
|
old.freelist, old.counters,
|
|
new.freelist, new.counters,
|
|
new.freelist, new.counters,
|
|
"unfreezing slab"));
|
|
"unfreezing slab"));
|
|
|
|
|
|
- if (m == M_FREE) {
|
|
|
|
|
|
+ if (unlikely(!new.inuse && n->nr_partial > s->min_partial)) {
|
|
page->next = discard_page;
|
|
page->next = discard_page;
|
|
discard_page = page;
|
|
discard_page = page;
|
|
|
|
+ } else {
|
|
|
|
+ add_partial(n, page, DEACTIVATE_TO_TAIL);
|
|
|
|
+ stat(s, FREE_ADD_PARTIAL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|