Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

md: convert to kvmalloc

The code really just wants a big flat buffer, so just do that.

Link: http://lkml.kernel.org/r/20181217131929.11727-3-kent.overstreet@gmail.com
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Reviewed-by: Matthew Wilcox <willy@infradead.org>
Cc: Shaohua Li <shli@kernel.org>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Eric Paris <eparis@parisplace.org>
Cc: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Cc: Neil Horman <nhorman@tuxdriver.com>
Cc: Paul Moore <paul@paul-moore.com>
Cc: Pravin B Shelar <pshelar@ovn.org>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: Vlad Yasevich <vyasevich@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Kent Overstreet and committed by
Linus Torvalds
b330e6a4 ee9c5e67

+45 -55
+2 -4
drivers/md/raid5-ppl.c
··· 16 16 #include <linux/blkdev.h> 17 17 #include <linux/slab.h> 18 18 #include <linux/crc32c.h> 19 - #include <linux/flex_array.h> 20 19 #include <linux/async_tx.h> 21 20 #include <linux/raid/md_p.h> 22 21 #include "md.h" ··· 164 165 struct dma_async_tx_descriptor *tx) 165 166 { 166 167 int disks = sh->disks; 167 - struct page **srcs = flex_array_get(percpu->scribble, 0); 168 + struct page **srcs = percpu->scribble; 168 169 int count = 0, pd_idx = sh->pd_idx, i; 169 170 struct async_submit_ctl submit; 170 171 ··· 195 196 } 196 197 197 198 init_async_submit(&submit, ASYNC_TX_FENCE|ASYNC_TX_XOR_ZERO_DST, tx, 198 - NULL, sh, flex_array_get(percpu->scribble, 0) 199 - + sizeof(struct page *) * (sh->disks + 2)); 199 + NULL, sh, (void *) (srcs + sh->disks + 2)); 200 200 201 201 if (count == 1) 202 202 tx = async_memcpy(sh->ppl_page, srcs[0], 0, 0, PAGE_SIZE,
+38 -47
drivers/md/raid5.c
··· 54 54 #include <linux/slab.h> 55 55 #include <linux/ratelimit.h> 56 56 #include <linux/nodemask.h> 57 - #include <linux/flex_array.h> 58 57 59 58 #include <trace/events/block.h> 60 59 #include <linux/list_sort.h> ··· 1393 1394 } 1394 1395 1395 1396 /* return a pointer to the address conversion region of the scribble buffer */ 1396 - static addr_conv_t *to_addr_conv(struct stripe_head *sh, 1397 - struct raid5_percpu *percpu, int i) 1397 + static struct page **to_addr_page(struct raid5_percpu *percpu, int i) 1398 1398 { 1399 - void *addr; 1400 - 1401 - addr = flex_array_get(percpu->scribble, i); 1402 - return addr + sizeof(struct page *) * (sh->disks + 2); 1399 + return percpu->scribble + i * percpu->scribble_obj_size; 1403 1400 } 1404 1401 1405 1402 /* return a pointer to the address conversion region of the scribble buffer */ 1406 - static struct page **to_addr_page(struct raid5_percpu *percpu, int i) 1403 + static addr_conv_t *to_addr_conv(struct stripe_head *sh, 1404 + struct raid5_percpu *percpu, int i) 1407 1405 { 1408 - void *addr; 1409 - 1410 - addr = flex_array_get(percpu->scribble, i); 1411 - return addr; 1406 + return (void *) (to_addr_page(percpu, i) + sh->disks + 2); 1412 1407 } 1413 1408 1414 1409 static struct dma_async_tx_descriptor * ··· 2231 2238 * calculate over all devices (not just the data blocks), using zeros in place 2232 2239 * of the P and Q blocks. 2233 2240 */ 2234 - static struct flex_array *scribble_alloc(int num, int cnt, gfp_t flags) 2241 + static int scribble_alloc(struct raid5_percpu *percpu, 2242 + int num, int cnt, gfp_t flags) 2235 2243 { 2236 - struct flex_array *ret; 2237 - size_t len; 2244 + size_t obj_size = 2245 + sizeof(struct page *) * (num+2) + 2246 + sizeof(addr_conv_t) * (num+2); 2247 + void *scribble; 2238 2248 2239 - len = sizeof(struct page *) * (num+2) + sizeof(addr_conv_t) * (num+2); 2240 - ret = flex_array_alloc(len, cnt, flags); 2241 - if (!ret) 2242 - return NULL; 2243 - /* always prealloc all elements, so no locking is required */ 2244 - if (flex_array_prealloc(ret, 0, cnt, flags)) { 2245 - flex_array_free(ret); 2246 - return NULL; 2247 - } 2248 - return ret; 2249 + scribble = kvmalloc_array(cnt, obj_size, flags); 2250 + if (!scribble) 2251 + return -ENOMEM; 2252 + 2253 + kvfree(percpu->scribble); 2254 + 2255 + percpu->scribble = scribble; 2256 + percpu->scribble_obj_size = obj_size; 2257 + return 0; 2249 2258 } 2250 2259 2251 2260 static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors) ··· 2265 2270 return 0; 2266 2271 mddev_suspend(conf->mddev); 2267 2272 get_online_cpus(); 2273 + 2268 2274 for_each_present_cpu(cpu) { 2269 2275 struct raid5_percpu *percpu; 2270 - struct flex_array *scribble; 2271 2276 2272 2277 percpu = per_cpu_ptr(conf->percpu, cpu); 2273 - scribble = scribble_alloc(new_disks, 2274 - new_sectors / STRIPE_SECTORS, 2275 - GFP_NOIO); 2276 - 2277 - if (scribble) { 2278 - flex_array_free(percpu->scribble); 2279 - percpu->scribble = scribble; 2280 - } else { 2281 - err = -ENOMEM; 2278 + err = scribble_alloc(percpu, new_disks, 2279 + new_sectors / STRIPE_SECTORS, 2280 + GFP_NOIO); 2281 + if (err) 2282 2282 break; 2283 - } 2284 2283 } 2284 + 2285 2285 put_online_cpus(); 2286 2286 mddev_resume(conf->mddev); 2287 2287 if (!err) { ··· 6732 6742 static void free_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu) 6733 6743 { 6734 6744 safe_put_page(percpu->spare_page); 6735 - if (percpu->scribble) 6736 - flex_array_free(percpu->scribble); 6737 6745 percpu->spare_page = NULL; 6746 + kvfree(percpu->scribble); 6738 6747 percpu->scribble = NULL; 6739 6748 } 6740 6749 6741 6750 static int alloc_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu) 6742 6751 { 6743 - if (conf->level == 6 && !percpu->spare_page) 6752 + if (conf->level == 6 && !percpu->spare_page) { 6744 6753 percpu->spare_page = alloc_page(GFP_KERNEL); 6745 - if (!percpu->scribble) 6746 - percpu->scribble = scribble_alloc(max(conf->raid_disks, 6747 - conf->previous_raid_disks), 6748 - max(conf->chunk_sectors, 6749 - conf->prev_chunk_sectors) 6750 - / STRIPE_SECTORS, 6751 - GFP_KERNEL); 6754 + if (!percpu->spare_page) 6755 + return -ENOMEM; 6756 + } 6752 6757 6753 - if (!percpu->scribble || (conf->level == 6 && !percpu->spare_page)) { 6758 + if (scribble_alloc(percpu, 6759 + max(conf->raid_disks, 6760 + conf->previous_raid_disks), 6761 + max(conf->chunk_sectors, 6762 + conf->prev_chunk_sectors) 6763 + / STRIPE_SECTORS, 6764 + GFP_KERNEL)) { 6754 6765 free_scratch_buffer(conf, percpu); 6755 6766 return -ENOMEM; 6756 6767 }
+5 -4
drivers/md/raid5.h
··· 638 638 /* per cpu variables */ 639 639 struct raid5_percpu { 640 640 struct page *spare_page; /* Used when checking P/Q in raid6 */ 641 - struct flex_array *scribble; /* space for constructing buffer 642 - * lists and performing address 643 - * conversions 644 - */ 641 + void *scribble; /* space for constructing buffer 642 + * lists and performing address 643 + * conversions 644 + */ 645 + int scribble_obj_size; 645 646 } __percpu *percpu; 646 647 int scribble_disks; 647 648 int scribble_sectors;