From: Christoph Lameter <cl@linux.com>
To: akpm@linuxfoundation.org
Cc: rostedt@goodmis.org, linux-kernel@vger.kernel.org,
Thomas Gleixner <tglx@linutronix.de>,
linux-mm@kvack.org, penberg@kernel.org, iamjoonsoo@lge.com,
Jesper Dangaard Brouer <brouer@redhat.com>
Subject: [PATCH 7/7] slub: Remove preemption disable/enable from fastpath
Date: Wed, 10 Dec 2014 10:30:24 -0600 [thread overview]
Message-ID: <20141210163034.199347747@linux.com> (raw)
In-Reply-To: 20141210163017.092096069@linux.com
[-- Attachment #1: slub_fastpath_remove_preempt --]
[-- Type: text/plain, Size: 4126 bytes --]
We can now use a this_cpu_cmpxchg_double to update two 64
bit values that are the entire description of the per cpu
freelist. There is no need anymore to disable preempt.
Signed-off-by: Christoph Lameter <cl@linux.com>
Index: linux/mm/slub.c
===================================================================
--- linux.orig/mm/slub.c 2014-12-09 12:31:45.867575731 -0600
+++ linux/mm/slub.c 2014-12-09 12:31:45.867575731 -0600
@@ -2272,21 +2272,15 @@ static inline void *get_freelist(struct
* a call to the page allocator and the setup of a new slab.
*/
static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
- unsigned long addr, struct kmem_cache_cpu *c)
+ unsigned long addr)
{
void *freelist;
struct page *page;
unsigned long flags;
+ struct kmem_cache_cpu *c;
local_irq_save(flags);
-#ifdef CONFIG_PREEMPT
- /*
- * We may have been preempted and rescheduled on a different
- * cpu before disabling interrupts. Need to reload cpu area
- * pointer.
- */
c = this_cpu_ptr(s->cpu_slab);
-#endif
if (!c->freelist || is_end_token(c->freelist))
goto new_slab;
@@ -2397,7 +2391,6 @@ static __always_inline void *slab_alloc_
gfp_t gfpflags, int node, unsigned long addr)
{
void **object;
- struct kmem_cache_cpu *c;
unsigned long tid;
if (slab_pre_alloc_hook(s, gfpflags))
@@ -2406,31 +2399,15 @@ static __always_inline void *slab_alloc_
s = memcg_kmem_get_cache(s, gfpflags);
redo:
/*
- * Must read kmem_cache cpu data via this cpu ptr. Preemption is
- * enabled. We may switch back and forth between cpus while
- * reading from one cpu area. That does not matter as long
- * as we end up on the original cpu again when doing the cmpxchg.
- *
- * Preemption is disabled for the retrieval of the tid because that
- * must occur from the current processor. We cannot allow rescheduling
- * on a different processor between the determination of the pointer
- * and the retrieval of the tid.
- */
- preempt_disable();
- c = this_cpu_ptr(s->cpu_slab);
-
- /*
* The transaction ids are globally unique per cpu and per operation on
* a per cpu queue. Thus they can be guarantee that the cmpxchg_double
* occurs on the right processor and that there was no operation on the
* linked list in between.
*/
- tid = c->tid;
- preempt_enable();
-
- object = c->freelist;
- if (unlikely(!object || is_end_token(object) ||!node_match_ptr(object, node))) {
- object = __slab_alloc(s, gfpflags, node, addr, c);
+ tid = this_cpu_read(s->cpu_slab->tid);
+ object = this_cpu_read(s->cpu_slab->freelist);
+ if (unlikely(!object || is_end_token(object) || !node_match_ptr(object, node))) {
+ object = __slab_alloc(s, gfpflags, node, addr);
stat(s, ALLOC_SLOWPATH);
} else {
void *next_object = get_freepointer_safe(s, object);
@@ -2666,30 +2643,21 @@ static __always_inline void slab_free(st
struct page *page, void *x, unsigned long addr)
{
void **object = (void *)x;
- struct kmem_cache_cpu *c;
+ void *freelist;
unsigned long tid;
slab_free_hook(s, x);
redo:
- /*
- * Determine the currently cpus per cpu slab.
- * The cpu may change afterward. However that does not matter since
- * data is retrieved via this pointer. If we are on the same cpu
- * during the cmpxchg then the free will succedd.
- */
- preempt_disable();
- c = this_cpu_ptr(s->cpu_slab);
-
- tid = c->tid;
- preempt_enable();
+ tid = this_cpu_read(s->cpu_slab->tid);
+ freelist = this_cpu_read(s->cpu_slab->freelist);
- if (likely(same_slab_page(s, page, c->freelist))) {
- set_freepointer(s, object, c->freelist);
+ if (likely(same_slab_page(s, page, freelist))) {
+ set_freepointer(s, object, freelist);
if (unlikely(!this_cpu_cmpxchg_double(
s->cpu_slab->freelist, s->cpu_slab->tid,
- c->freelist, tid,
+ freelist, tid,
object, next_tid(tid)))) {
note_cmpxchg_failure("slab_free", s, tid);
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
WARNING: multiple messages have this Message-ID (diff)
From: Christoph Lameter <cl@linux.com>
To: akpm@linuxfoundation.org
Cc: rostedt@goodmis.org, linux-kernel@vger.kernel.org,
Thomas Gleixner <tglx@linutronix.de>
Cc: linux-mm@kvack.org, penberg@kernel.org, iamjoonsoo@lge.com,
Jesper Dangaard Brouer <brouer@redhat.com>
Subject: [PATCH 7/7] slub: Remove preemption disable/enable from fastpath
Date: Wed, 10 Dec 2014 10:30:24 -0600 [thread overview]
Message-ID: <20141210163034.199347747@linux.com> (raw)
In-Reply-To: 20141210163017.092096069@linux.com
[-- Attachment #1: slub_fastpath_remove_preempt --]
[-- Type: text/plain, Size: 3901 bytes --]
We can now use a this_cpu_cmpxchg_double to update two 64
bit values that are the entire description of the per cpu
freelist. There is no need anymore to disable preempt.
Signed-off-by: Christoph Lameter <cl@linux.com>
Index: linux/mm/slub.c
===================================================================
--- linux.orig/mm/slub.c 2014-12-09 12:31:45.867575731 -0600
+++ linux/mm/slub.c 2014-12-09 12:31:45.867575731 -0600
@@ -2272,21 +2272,15 @@ static inline void *get_freelist(struct
* a call to the page allocator and the setup of a new slab.
*/
static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
- unsigned long addr, struct kmem_cache_cpu *c)
+ unsigned long addr)
{
void *freelist;
struct page *page;
unsigned long flags;
+ struct kmem_cache_cpu *c;
local_irq_save(flags);
-#ifdef CONFIG_PREEMPT
- /*
- * We may have been preempted and rescheduled on a different
- * cpu before disabling interrupts. Need to reload cpu area
- * pointer.
- */
c = this_cpu_ptr(s->cpu_slab);
-#endif
if (!c->freelist || is_end_token(c->freelist))
goto new_slab;
@@ -2397,7 +2391,6 @@ static __always_inline void *slab_alloc_
gfp_t gfpflags, int node, unsigned long addr)
{
void **object;
- struct kmem_cache_cpu *c;
unsigned long tid;
if (slab_pre_alloc_hook(s, gfpflags))
@@ -2406,31 +2399,15 @@ static __always_inline void *slab_alloc_
s = memcg_kmem_get_cache(s, gfpflags);
redo:
/*
- * Must read kmem_cache cpu data via this cpu ptr. Preemption is
- * enabled. We may switch back and forth between cpus while
- * reading from one cpu area. That does not matter as long
- * as we end up on the original cpu again when doing the cmpxchg.
- *
- * Preemption is disabled for the retrieval of the tid because that
- * must occur from the current processor. We cannot allow rescheduling
- * on a different processor between the determination of the pointer
- * and the retrieval of the tid.
- */
- preempt_disable();
- c = this_cpu_ptr(s->cpu_slab);
-
- /*
* The transaction ids are globally unique per cpu and per operation on
* a per cpu queue. Thus they can be guarantee that the cmpxchg_double
* occurs on the right processor and that there was no operation on the
* linked list in between.
*/
- tid = c->tid;
- preempt_enable();
-
- object = c->freelist;
- if (unlikely(!object || is_end_token(object) ||!node_match_ptr(object, node))) {
- object = __slab_alloc(s, gfpflags, node, addr, c);
+ tid = this_cpu_read(s->cpu_slab->tid);
+ object = this_cpu_read(s->cpu_slab->freelist);
+ if (unlikely(!object || is_end_token(object) || !node_match_ptr(object, node))) {
+ object = __slab_alloc(s, gfpflags, node, addr);
stat(s, ALLOC_SLOWPATH);
} else {
void *next_object = get_freepointer_safe(s, object);
@@ -2666,30 +2643,21 @@ static __always_inline void slab_free(st
struct page *page, void *x, unsigned long addr)
{
void **object = (void *)x;
- struct kmem_cache_cpu *c;
+ void *freelist;
unsigned long tid;
slab_free_hook(s, x);
redo:
- /*
- * Determine the currently cpus per cpu slab.
- * The cpu may change afterward. However that does not matter since
- * data is retrieved via this pointer. If we are on the same cpu
- * during the cmpxchg then the free will succedd.
- */
- preempt_disable();
- c = this_cpu_ptr(s->cpu_slab);
-
- tid = c->tid;
- preempt_enable();
+ tid = this_cpu_read(s->cpu_slab->tid);
+ freelist = this_cpu_read(s->cpu_slab->freelist);
- if (likely(same_slab_page(s, page, c->freelist))) {
- set_freepointer(s, object, c->freelist);
+ if (likely(same_slab_page(s, page, freelist))) {
+ set_freepointer(s, object, freelist);
if (unlikely(!this_cpu_cmpxchg_double(
s->cpu_slab->freelist, s->cpu_slab->tid,
- c->freelist, tid,
+ freelist, tid,
object, next_tid(tid)))) {
note_cmpxchg_failure("slab_free", s, tid);
next prev parent reply other threads:[~2014-12-10 16:31 UTC|newest]
Thread overview: 100+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-12-10 16:30 [PATCH 0/7] slub: Fastpath optimization (especially for RT) V1 Christoph Lameter
2014-12-10 16:30 ` Christoph Lameter
2014-12-10 16:30 ` [PATCH 1/7] slub: Remove __slab_alloc code duplication Christoph Lameter
2014-12-10 16:30 ` Christoph Lameter
2014-12-10 16:39 ` Pekka Enberg
2014-12-10 16:39 ` Pekka Enberg
2014-12-10 16:30 ` [PATCH 2/7] slub: Use page-mapping to store address of page frame like done in SLAB Christoph Lameter
2014-12-10 16:30 ` Christoph Lameter
2014-12-10 16:45 ` Pekka Enberg
2014-12-10 16:45 ` Pekka Enberg
2014-12-10 16:30 ` [PATCH 3/7] slub: Do not use c->page on free Christoph Lameter
2014-12-10 16:30 ` Christoph Lameter
2014-12-10 16:54 ` Pekka Enberg
2014-12-10 16:54 ` Pekka Enberg
2014-12-10 17:08 ` Christoph Lameter
2014-12-10 17:08 ` Christoph Lameter
2014-12-10 17:32 ` Pekka Enberg
2014-12-10 17:32 ` Pekka Enberg
2014-12-10 17:37 ` Christoph Lameter
2014-12-10 17:37 ` Christoph Lameter
2014-12-11 13:19 ` Jesper Dangaard Brouer
2014-12-11 13:19 ` Jesper Dangaard Brouer
2014-12-11 15:01 ` Christoph Lameter
2014-12-11 15:01 ` Christoph Lameter
2014-12-15 8:03 ` Joonsoo Kim
2014-12-15 8:03 ` Joonsoo Kim
2014-12-15 14:16 ` Christoph Lameter
2014-12-15 14:16 ` Christoph Lameter
2014-12-16 2:42 ` Joonsoo Kim
2014-12-16 2:42 ` Joonsoo Kim
2014-12-16 7:54 ` Andrey Ryabinin
2014-12-16 7:54 ` Andrey Ryabinin
2014-12-16 8:25 ` Joonsoo Kim
2014-12-16 8:25 ` Joonsoo Kim
2014-12-16 14:53 ` Christoph Lameter
2014-12-16 14:53 ` Christoph Lameter
2014-12-16 15:15 ` Jesper Dangaard Brouer
2014-12-16 15:15 ` Jesper Dangaard Brouer
2014-12-16 15:34 ` Andrey Ryabinin
2014-12-16 15:34 ` Andrey Ryabinin
2014-12-16 15:48 ` Christoph Lameter
2014-12-16 15:48 ` Christoph Lameter
2014-12-17 7:15 ` Joonsoo Kim
2014-12-17 7:15 ` Joonsoo Kim
2014-12-16 15:33 ` Andrey Ryabinin
2014-12-16 15:33 ` Andrey Ryabinin
2014-12-16 14:05 ` Jesper Dangaard Brouer
2014-12-16 14:05 ` Jesper Dangaard Brouer
2014-12-10 16:30 ` [PATCH 4/7] slub: Avoid using the page struct address in allocation fastpath Christoph Lameter
2014-12-10 16:30 ` Christoph Lameter
2014-12-10 16:56 ` Pekka Enberg
2014-12-10 16:56 ` Pekka Enberg
2014-12-10 16:30 ` [PATCH 5/7] slub: Use end_token instead of NULL to terminate freelists Christoph Lameter
2014-12-10 16:30 ` Christoph Lameter
2014-12-10 16:59 ` Pekka Enberg
2014-12-10 16:59 ` Pekka Enberg
2014-12-10 16:30 ` [PATCH 6/7] slub: Drop ->page field from kmem_cache_cpu Christoph Lameter
2014-12-10 16:30 ` Christoph Lameter
2014-12-10 17:29 ` Pekka Enberg
2014-12-10 17:29 ` Pekka Enberg
2014-12-10 16:30 ` Christoph Lameter [this message]
2014-12-10 16:30 ` [PATCH 7/7] slub: Remove preemption disable/enable from fastpath Christoph Lameter
2014-12-11 13:35 ` [PATCH 0/7] slub: Fastpath optimization (especially for RT) V1 Jesper Dangaard Brouer
2014-12-11 13:35 ` Jesper Dangaard Brouer
2014-12-11 15:03 ` Christoph Lameter
2014-12-11 15:03 ` Christoph Lameter
2014-12-11 16:50 ` Jesper Dangaard Brouer
2014-12-11 16:50 ` Jesper Dangaard Brouer
2014-12-11 17:18 ` Christoph Lameter
2014-12-11 17:18 ` Christoph Lameter
2014-12-11 18:11 ` Jesper Dangaard Brouer
2014-12-11 18:11 ` Jesper Dangaard Brouer
2014-12-11 17:37 ` Jesper Dangaard Brouer
2014-12-11 17:37 ` Jesper Dangaard Brouer
2014-12-12 10:39 ` Jesper Dangaard Brouer
2014-12-12 10:39 ` Jesper Dangaard Brouer
2014-12-12 18:31 ` Christoph Lameter
2014-12-12 18:31 ` Christoph Lameter
2014-12-15 7:59 ` Joonsoo Kim
2014-12-15 7:59 ` Joonsoo Kim
2014-12-17 7:13 ` Joonsoo Kim
2014-12-17 7:13 ` Joonsoo Kim
2014-12-17 12:08 ` Jesper Dangaard Brouer
2014-12-17 12:08 ` Jesper Dangaard Brouer
2014-12-18 14:34 ` Joonsoo Kim
2014-12-18 14:34 ` Joonsoo Kim
2014-12-17 15:36 ` Christoph Lameter
2014-12-17 15:36 ` Christoph Lameter
2014-12-18 14:38 ` Joonsoo Kim
2014-12-18 14:38 ` Joonsoo Kim
2014-12-18 14:57 ` Christoph Lameter
2014-12-18 14:57 ` Christoph Lameter
2014-12-18 15:08 ` Joonsoo Kim
2014-12-18 15:08 ` Joonsoo Kim
2014-12-17 16:10 ` Christoph Lameter
2014-12-17 16:10 ` Christoph Lameter
2014-12-17 19:44 ` Christoph Lameter
2014-12-17 19:44 ` Christoph Lameter
2014-12-18 14:41 ` Joonsoo Kim
2014-12-18 14:41 ` Joonsoo Kim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20141210163034.199347747@linux.com \
--to=cl@linux.com \
--cc=akpm@linuxfoundation.org \
--cc=brouer@redhat.com \
--cc=iamjoonsoo@lge.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=penberg@kernel.org \
--cc=rostedt@goodmis.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.