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: Mikulas Patocka <mpatocka@redhat.com> Cc: stable@vger.kernel.org Signed-off-by: Mike Snitzer <snitzer@redhat.com>
This commit is contained in:
parent
114e025968
commit
856eb0916d
|
@ -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 {
|
||||||
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)
|
||||||
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 @@ bad_io_barrier:
|
||||||
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)
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue