rcu: don't assume the size of struct rcu_head
Subsystems (4)
cover rcu: don't assume the size of struct rcu_head
We always keep the struct rcu_head very small, but we may change it in future or under some CONFIGs.
There are some other systems may assume the size of struct rcu_head as 2 * sizeof(long). These assumptions obstruct us to add debug information or priority information to struct rcu_head. It is time to fix them.
It is glad that I just find 3 places which need to be fixed. These 4 patches are just cleanup patches when the size of struct rcu_head == 2 * sizeof(long). NO overhead added and NO behavior changed.
Even when the size of struct rcu_head becomes larger, only slub is changed a little.
---
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH v2 1/3 slub: automatically reserve bytes at the end of slab
There is no "struct" for slub's slab, it shares with struct page. But struct page is very small, it is insufficient when we need to add some metadata for slab.
So we add a field "reserved" to struct kmem_cache, when a slab is allocated, kmem_cache->reserved bytes are automatically reserved at the end of the slab for slab's metadata.
Changed from v1:
Export the reserved field via sysfs
--- include/linux/slub_def.h | 1 + mm/slub.c | 47 +++++++++++++++++++++++++++++---------------- 2 files changed, 31 insertions(+), 17 deletions(-)
include/linux/slub_def.h +1 -0
@@ -83,6 +83,7 @@ struct kmem_cache {void (*ctor)(void *);int inuse;/* Offset to metadata */ int align;/* Alignment */ +int reserved;/* Reserved bytes at the end of slabs */ unsigned long min_partial;const char *name;/* Name (only for display!) */ struct list_head list;/* List of slab caches */
mm/slub.c +30 -17
153 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/3 V2] slub: automatically reserve bytes at the end of slab
PATCH v2 2/3 slub,rcu: don't assume the size of struct rcu_head
In reply to Lai JiangshanThe size of struct rcu_head may be changed. When it becomes larger, it will pollute the page array.
We reserve some some bytes for struct rcu_head when a slab is allocated in this situation.
Changed from V1:
use VM_BUG_ON instead BUG_ON
--- mm/slub.c | 30 +++++++++++++++++++++++++----- 1 files changed, 25 insertions(+), 5 deletions(-)
mm/slub.c +25 -5
@@ -1254,21 +1254,38 @@ static void __free_slab(struct kmem_cache *s, struct page *page)__free_pages (page, order); } +#define need_reserve_slab_rcu \ + (sizeof(((struct page *)NULL)->lru) < sizeof(struct rcu_head)) +static void rcu_free_slab (struct rcu_head *h) {struct page *page; - page = container_of((struct list_head *)h, struct page, lru); +if (need_reserve_slab_rcu) + page =virt_to_head_page (h); +else + page = container_of((struct list_head *)h, struct page, lru); +__free_slab (page->slab, page); }static void free_slab (struct kmem_cache *s,struct page *page) {if (unlikely (s->flags &SLAB_DESTROY_BY_RCU )) { -/* -* RCU free overloads the RCU head over the LRU -*/ -struct rcu_head *head = (void *)&page->lru; +struct rcu_head *head; + +if (need_reserve_slab_rcu) { +int order =compound_order (page); +int offset = (PAGE_SIZE << order) - s->reserved; + +VM_BUG_ON (s->reserved !=sizeof (*head)); + head =page_address (page) + offset; + }else { +/* +* RCU free overloads the RCU head over the LRU +*/ + head = (void *)&page->lru; + }call_rcu (head, rcu_free_slab); }else
@@ -2356,6 +2373,9 @@ static int kmem_cache_open(struct kmem_cache *s, s->flags =kmem_cache_flags (size, flags, name, ctor); s->reserved =0 ; +if (need_reserve_slab_rcu && (s->flags &SLAB_DESTROY_BY_RCU )) + s->reserved =sizeof (struct rcu_head ); +if (!calculate_sizes (s,-1 )) goto error;if (disable_higher_order_debug) {
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/3 V2] slub,rcu: don't assume the size of struct rcu_head
PATCH v2 3/3 slab,rcu: don't assume the size of struct rcu_head
In reply to Lai JiangshanThe size of struct rcu_head may be changed. When it becomes larger, it may pollute the data after struct slab.
---
mm/slab.c +21 -18
@@ -191,22 +191,6 @@ typedef unsigned int kmem_bufctl_t;#define SLAB_LIMIT (((kmem_bufctl_t)(~0U))-3)/* -* struct slab -* -* Manages the objs in a slab. Placed either at the beginning of mem allocated -* for a slab, or allocated from an general cache. -* Slabs are chained into three list: fully used, partial, fully free slabs. -*/ -struct slab { -struct list_head list; -unsigned long colouroff; -void *s_mem;/* including colour offset */ -unsigned int inuse;/* num of objs active in slab */ -kmem_bufctl_t free; -unsigned short nodeid; -}; - -/* * struct slab_rcu * * slab_destroy on a SLAB_DESTROY_BY_RCU cache uses this structure to
@@ -219,8 +203,6 @@ struct slab {* * rcu_read_lock before reading the address, then rcu_read_unlock after * taking the spinlock within the structure expected at that address. -* -* We assume struct slab_rcu can overlay struct slab when destroying. */ struct slab_rcu {struct rcu_head head;
@@ -229,6 +211,27 @@ struct slab_rcu { };/* +* struct slab +* +* Manages the objs in a slab. Placed either at the beginning of mem allocated +* for a slab, or allocated from an general cache. +* Slabs are chained into three list: fully used, partial, fully free slabs. +*/ +struct slab { +union { +struct { +struct list_head list; +unsigned long colouroff; +void *s_mem;/* including colour offset */ +unsigned int inuse;/* num of objs active in slab */ +kmem_bufctl_t free; +unsigned short nodeid; + }; +struct slab_rcu __slab_cover_slab_rcu; + }; +}; + +/* * struct array_cache * * Purpose:
--
Re: [PATCH 3/3 V2] slab,rcu: don't assume the size of struct rcu_head