Skip to content

Commit

Permalink
dm verity fec: fix GFP flags used with mempool_alloc()
Browse files Browse the repository at this point in the history
mempool_alloc() cannot fail for GFP_NOIO allocation, so there is no
point testing for failure.

One place the code tested for failure was passing "0" as the GFP
flags.  This is most unusual and is probably meant to be GFP_NOIO,
so that is changed.

Also, allocation from ->extra_pool and ->prealloc_pool are repeated
before releasing the previous allocation.  This can deadlock if the code
is servicing a write under high memory pressure.  To avoid deadlocks,
change these to use GFP_NOWAIT and leave the error handling in place.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
  • Loading branch information
NeilBrown authored and Mike Snitzer committed Jul 26, 2017
1 parent 4218a95 commit 34c9650
Showing 1 changed file with 5 additions and 16 deletions.
21 changes: 5 additions & 16 deletions drivers/md/dm-verity-fec.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,19 +308,14 @@ static int fec_alloc_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio)
{
unsigned n;

if (!fio->rs) {
fio->rs = mempool_alloc(v->fec->rs_pool, 0);
if (unlikely(!fio->rs)) {
DMERR("failed to allocate RS");
return -ENOMEM;
}
}
if (!fio->rs)
fio->rs = mempool_alloc(v->fec->rs_pool, GFP_NOIO);

fec_for_each_prealloc_buffer(n) {
if (fio->bufs[n])
continue;

fio->bufs[n] = mempool_alloc(v->fec->prealloc_pool, GFP_NOIO);
fio->bufs[n] = mempool_alloc(v->fec->prealloc_pool, GFP_NOWAIT);
if (unlikely(!fio->bufs[n])) {
DMERR("failed to allocate FEC buffer");
return -ENOMEM;
Expand All @@ -332,22 +327,16 @@ static int fec_alloc_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio)
if (fio->bufs[n])
continue;

fio->bufs[n] = mempool_alloc(v->fec->extra_pool, GFP_NOIO);
fio->bufs[n] = mempool_alloc(v->fec->extra_pool, GFP_NOWAIT);
/* we can manage with even one buffer if necessary */
if (unlikely(!fio->bufs[n]))
break;
}
fio->nbufs = n;

if (!fio->output) {
if (!fio->output)
fio->output = mempool_alloc(v->fec->output_pool, GFP_NOIO);

if (!fio->output) {
DMERR("failed to allocate FEC page");
return -ENOMEM;
}
}

return 0;
}

Expand Down

0 comments on commit 34c9650

Please sign in to comment.