Skip to content

Commit b330e6a

Browse files
koverstreettorvalds
authored andcommitted
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>
1 parent ee9c5e6 commit b330e6a

File tree

3 files changed

+46
-56
lines changed

3 files changed

+46
-56
lines changed

drivers/md/raid5-ppl.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include <linux/blkdev.h>
1717
#include <linux/slab.h>
1818
#include <linux/crc32c.h>
19-
#include <linux/flex_array.h>
2019
#include <linux/async_tx.h>
2120
#include <linux/raid/md_p.h>
2221
#include "md.h"
@@ -165,7 +164,7 @@ ops_run_partial_parity(struct stripe_head *sh, struct raid5_percpu *percpu,
165164
struct dma_async_tx_descriptor *tx)
166165
{
167166
int disks = sh->disks;
168-
struct page **srcs = flex_array_get(percpu->scribble, 0);
167+
struct page **srcs = percpu->scribble;
169168
int count = 0, pd_idx = sh->pd_idx, i;
170169
struct async_submit_ctl submit;
171170

@@ -196,8 +195,7 @@ ops_run_partial_parity(struct stripe_head *sh, struct raid5_percpu *percpu,
196195
}
197196

198197
init_async_submit(&submit, ASYNC_TX_FENCE|ASYNC_TX_XOR_ZERO_DST, tx,
199-
NULL, sh, flex_array_get(percpu->scribble, 0)
200-
+ sizeof(struct page *) * (sh->disks + 2));
198+
NULL, sh, (void *) (srcs + sh->disks + 2));
201199

202200
if (count == 1)
203201
tx = async_memcpy(sh->ppl_page, srcs[0], 0, 0, PAGE_SIZE,

drivers/md/raid5.c

Lines changed: 39 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
#include <linux/slab.h>
5555
#include <linux/ratelimit.h>
5656
#include <linux/nodemask.h>
57-
#include <linux/flex_array.h>
5857

5958
#include <trace/events/block.h>
6059
#include <linux/list_sort.h>
@@ -1394,22 +1393,16 @@ static void ops_complete_compute(void *stripe_head_ref)
13941393
}
13951394

13961395
/* return a pointer to the address conversion region of the scribble buffer */
1397-
static addr_conv_t *to_addr_conv(struct stripe_head *sh,
1398-
struct raid5_percpu *percpu, int i)
1396+
static struct page **to_addr_page(struct raid5_percpu *percpu, int i)
13991397
{
1400-
void *addr;
1401-
1402-
addr = flex_array_get(percpu->scribble, i);
1403-
return addr + sizeof(struct page *) * (sh->disks + 2);
1398+
return percpu->scribble + i * percpu->scribble_obj_size;
14041399
}
14051400

14061401
/* return a pointer to the address conversion region of the scribble buffer */
1407-
static struct page **to_addr_page(struct raid5_percpu *percpu, int i)
1402+
static addr_conv_t *to_addr_conv(struct stripe_head *sh,
1403+
struct raid5_percpu *percpu, int i)
14081404
{
1409-
void *addr;
1410-
1411-
addr = flex_array_get(percpu->scribble, i);
1412-
return addr;
1405+
return (void *) (to_addr_page(percpu, i) + sh->disks + 2);
14131406
}
14141407

14151408
static struct dma_async_tx_descriptor *
@@ -2238,21 +2231,23 @@ static int grow_stripes(struct r5conf *conf, int num)
22382231
* calculate over all devices (not just the data blocks), using zeros in place
22392232
* of the P and Q blocks.
22402233
*/
2241-
static struct flex_array *scribble_alloc(int num, int cnt, gfp_t flags)
2234+
static int scribble_alloc(struct raid5_percpu *percpu,
2235+
int num, int cnt, gfp_t flags)
22422236
{
2243-
struct flex_array *ret;
2244-
size_t len;
2237+
size_t obj_size =
2238+
sizeof(struct page *) * (num+2) +
2239+
sizeof(addr_conv_t) * (num+2);
2240+
void *scribble;
22452241

2246-
len = sizeof(struct page *) * (num+2) + sizeof(addr_conv_t) * (num+2);
2247-
ret = flex_array_alloc(len, cnt, flags);
2248-
if (!ret)
2249-
return NULL;
2250-
/* always prealloc all elements, so no locking is required */
2251-
if (flex_array_prealloc(ret, 0, cnt, flags)) {
2252-
flex_array_free(ret);
2253-
return NULL;
2254-
}
2255-
return ret;
2242+
scribble = kvmalloc_array(cnt, obj_size, flags);
2243+
if (!scribble)
2244+
return -ENOMEM;
2245+
2246+
kvfree(percpu->scribble);
2247+
2248+
percpu->scribble = scribble;
2249+
percpu->scribble_obj_size = obj_size;
2250+
return 0;
22562251
}
22572252

22582253
static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors)
@@ -2270,23 +2265,18 @@ static int resize_chunks(struct r5conf *conf, int new_disks, int new_sectors)
22702265
return 0;
22712266
mddev_suspend(conf->mddev);
22722267
get_online_cpus();
2268+
22732269
for_each_present_cpu(cpu) {
22742270
struct raid5_percpu *percpu;
2275-
struct flex_array *scribble;
22762271

22772272
percpu = per_cpu_ptr(conf->percpu, cpu);
2278-
scribble = scribble_alloc(new_disks,
2279-
new_sectors / STRIPE_SECTORS,
2280-
GFP_NOIO);
2281-
2282-
if (scribble) {
2283-
flex_array_free(percpu->scribble);
2284-
percpu->scribble = scribble;
2285-
} else {
2286-
err = -ENOMEM;
2273+
err = scribble_alloc(percpu, new_disks,
2274+
new_sectors / STRIPE_SECTORS,
2275+
GFP_NOIO);
2276+
if (err)
22872277
break;
2288-
}
22892278
}
2279+
22902280
put_online_cpus();
22912281
mddev_resume(conf->mddev);
22922282
if (!err) {
@@ -6742,25 +6732,26 @@ raid5_size(struct mddev *mddev, sector_t sectors, int raid_disks)
67426732
static void free_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu)
67436733
{
67446734
safe_put_page(percpu->spare_page);
6745-
if (percpu->scribble)
6746-
flex_array_free(percpu->scribble);
67476735
percpu->spare_page = NULL;
6736+
kvfree(percpu->scribble);
67486737
percpu->scribble = NULL;
67496738
}
67506739

67516740
static int alloc_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu)
67526741
{
6753-
if (conf->level == 6 && !percpu->spare_page)
6742+
if (conf->level == 6 && !percpu->spare_page) {
67546743
percpu->spare_page = alloc_page(GFP_KERNEL);
6755-
if (!percpu->scribble)
6756-
percpu->scribble = scribble_alloc(max(conf->raid_disks,
6757-
conf->previous_raid_disks),
6758-
max(conf->chunk_sectors,
6759-
conf->prev_chunk_sectors)
6760-
/ STRIPE_SECTORS,
6761-
GFP_KERNEL);
6762-
6763-
if (!percpu->scribble || (conf->level == 6 && !percpu->spare_page)) {
6744+
if (!percpu->spare_page)
6745+
return -ENOMEM;
6746+
}
6747+
6748+
if (scribble_alloc(percpu,
6749+
max(conf->raid_disks,
6750+
conf->previous_raid_disks),
6751+
max(conf->chunk_sectors,
6752+
conf->prev_chunk_sectors)
6753+
/ STRIPE_SECTORS,
6754+
GFP_KERNEL)) {
67646755
free_scratch_buffer(conf, percpu);
67656756
return -ENOMEM;
67666757
}

drivers/md/raid5.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -638,10 +638,11 @@ struct r5conf {
638638
/* per cpu variables */
639639
struct raid5_percpu {
640640
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;
645646
} __percpu *percpu;
646647
int scribble_disks;
647648
int scribble_sectors;

0 commit comments

Comments
 (0)