summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.com>2017-04-09 22:13:00 -0400
committerMike Snitzer <snitzer@redhat.com>2017-07-26 15:55:44 -0400
commit34c96507e8f6be497c15497be05f489fb34c5880 (patch)
tree769ae87a18b139fc9c5cdd0c5172ab8aae017fcf
parent4218a9554653bd5be6e3c740749282b57434bd73 (diff)
dm verity fec: fix GFP flags used with mempool_alloc()
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>
-rw-r--r--drivers/md/dm-verity-fec.c21
1 files changed, 5 insertions, 16 deletions
diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c
index 504ba3fa328b..e13f90832b6b 100644
--- a/drivers/md/dm-verity-fec.c
+++ b/drivers/md/dm-verity-fec.c
@@ -308,19 +308,14 @@ static int fec_alloc_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio)
308{ 308{
309 unsigned n; 309 unsigned n;
310 310
311 if (!fio->rs) { 311 if (!fio->rs)
312 fio->rs = mempool_alloc(v->fec->rs_pool, 0); 312 fio->rs = mempool_alloc(v->fec->rs_pool, GFP_NOIO);
313 if (unlikely(!fio->rs)) {
314 DMERR("failed to allocate RS");
315 return -ENOMEM;
316 }
317 }
318 313
319 fec_for_each_prealloc_buffer(n) { 314 fec_for_each_prealloc_buffer(n) {
320 if (fio->bufs[n]) 315 if (fio->bufs[n])
321 continue; 316 continue;
322 317
323 fio->bufs[n] = mempool_alloc(v->fec->prealloc_pool, GFP_NOIO); 318 fio->bufs[n] = mempool_alloc(v->fec->prealloc_pool, GFP_NOWAIT);
324 if (unlikely(!fio->bufs[n])) { 319 if (unlikely(!fio->bufs[n])) {
325 DMERR("failed to allocate FEC buffer"); 320 DMERR("failed to allocate FEC buffer");
326 return -ENOMEM; 321 return -ENOMEM;
@@ -332,22 +327,16 @@ static int fec_alloc_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio)
332 if (fio->bufs[n]) 327 if (fio->bufs[n])
333 continue; 328 continue;
334 329
335 fio->bufs[n] = mempool_alloc(v->fec->extra_pool, GFP_NOIO); 330 fio->bufs[n] = mempool_alloc(v->fec->extra_pool, GFP_NOWAIT);
336 /* we can manage with even one buffer if necessary */ 331 /* we can manage with even one buffer if necessary */
337 if (unlikely(!fio->bufs[n])) 332 if (unlikely(!fio->bufs[n]))
338 break; 333 break;
339 } 334 }
340 fio->nbufs = n; 335 fio->nbufs = n;
341 336
342 if (!fio->output) { 337 if (!fio->output)
343 fio->output = mempool_alloc(v->fec->output_pool, GFP_NOIO); 338 fio->output = mempool_alloc(v->fec->output_pool, GFP_NOIO);
344 339
345 if (!fio->output) {
346 DMERR("failed to allocate FEC page");
347 return -ENOMEM;
348 }
349 }
350
351 return 0; 340 return 0;
352} 341}
353 342