summaryrefslogtreecommitdiffstats
path: root/drivers/md/dm.c
diff options
context:
space:
mode:
authorMikulas Patocka2017-11-01 00:33:02 +0100
committerMike Snitzer2017-11-10 21:44:55 +0100
commit856eb0916d181da6d043cc33e03f54d5c5bbe54a (patch)
tree37dc30db88b6b90a1f1929801acf97209b4548f8 /drivers/md/dm.c
parentdm zoned: ignore last smaller runt zone (diff)
downloadkernel-qcow2-linux-856eb0916d181da6d043cc33e03f54d5c5bbe54a.tar.gz
kernel-qcow2-linux-856eb0916d181da6d043cc33e03f54d5c5bbe54a.tar.xz
kernel-qcow2-linux-856eb0916d181da6d043cc33e03f54d5c5bbe54a.zip
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>
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r--drivers/md/dm.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index be12f3f12e9d..adb874c2411b 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1697,7 +1697,7 @@ static struct mapped_device *alloc_dev(int minor)
struct mapped_device *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) {
DMWARN("unable to allocate device, out of memory.");
return NULL;
@@ -1797,7 +1797,7 @@ bad_io_barrier:
bad_minor:
module_put(THIS_MODULE);
bad_module_get:
- kfree(md);
+ kvfree(md);
return NULL;
}
@@ -1816,7 +1816,7 @@ static void free_dev(struct mapped_device *md)
free_minor(minor);
module_put(THIS_MODULE);
- kfree(md);
+ kvfree(md);
}
static void __bind_mempools(struct mapped_device *md, struct dm_table *t)