Commit 856eb091 authored by Mikulas Patocka's avatar Mikulas Patocka Committed by Mike Snitzer

dm: allocate struct mapped_device with kvzalloc

The structure srcu_struct can be very big, its size is proportional to the
value CONFIG_NR_CPUS. The Fedora kernel has CONFIG_NR_CPUS 8192, the field
io_barrier in the struct mapped_device has 84kB in the debugging kernel
and 50kB in the non-debugging kernel. The large size may result in failure
of the function kzalloc_node.

In order to avoid the allocation failure, we use the function
kvzalloc_node, this function falls back to vmalloc if a large contiguous
chunk of memory is not available. This patch also moves the field
io_barrier to the last position of struct mapped_device - the reason is
that on many processor architectures, short memory offsets result in
smaller code than long memory offsets - on x86-64 it reduces code size by
320 bytes.

Note to stable kernel maintainers - the kernels 4.11 and older don't have
the function kvzalloc_node, you can use the function vzalloc_node instead.
Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent 114e0259
...@@ -29,7 +29,6 @@ struct dm_kobject_holder { ...@@ -29,7 +29,6 @@ struct dm_kobject_holder {
* DM targets must _not_ deference a mapped_device to directly access its members! * DM targets must _not_ deference a mapped_device to directly access its members!
*/ */
struct mapped_device { struct mapped_device {
struct srcu_struct io_barrier;
struct mutex suspend_lock; struct mutex suspend_lock;
/* /*
...@@ -127,6 +126,8 @@ struct mapped_device { ...@@ -127,6 +126,8 @@ struct mapped_device {
struct blk_mq_tag_set *tag_set; struct blk_mq_tag_set *tag_set;
bool use_blk_mq:1; bool use_blk_mq:1;
bool init_tio_pdu:1; bool init_tio_pdu:1;
struct srcu_struct io_barrier;
}; };
void dm_init_md_queue(struct mapped_device *md); void dm_init_md_queue(struct mapped_device *md);
......
...@@ -1697,7 +1697,7 @@ static struct mapped_device *alloc_dev(int minor) ...@@ -1697,7 +1697,7 @@ static struct mapped_device *alloc_dev(int minor)
struct mapped_device *md; struct mapped_device *md;
void *old_md; void *old_md;
md = kzalloc_node(sizeof(*md), GFP_KERNEL, numa_node_id); md = kvzalloc_node(sizeof(*md), GFP_KERNEL, numa_node_id);
if (!md) { if (!md) {
DMWARN("unable to allocate device, out of memory."); DMWARN("unable to allocate device, out of memory.");
return NULL; return NULL;
...@@ -1797,7 +1797,7 @@ static struct mapped_device *alloc_dev(int minor) ...@@ -1797,7 +1797,7 @@ static struct mapped_device *alloc_dev(int minor)
bad_minor: bad_minor:
module_put(THIS_MODULE); module_put(THIS_MODULE);
bad_module_get: bad_module_get:
kfree(md); kvfree(md);
return NULL; return NULL;
} }
...@@ -1816,7 +1816,7 @@ static void free_dev(struct mapped_device *md) ...@@ -1816,7 +1816,7 @@ static void free_dev(struct mapped_device *md)
free_minor(minor); free_minor(minor);
module_put(THIS_MODULE); module_put(THIS_MODULE);
kfree(md); kvfree(md);
} }
static void __bind_mempools(struct mapped_device *md, struct dm_table *t) static void __bind_mempools(struct mapped_device *md, struct dm_table *t)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment