Skip to content

Commit

Permalink
Use GFP_ATOMIC for allocations that are required for swap on zvols
Browse files Browse the repository at this point in the history
dmu_bio_clone(), __vdev_disk_physio() and vdev_disk_io_flush() are used
when doing swap to a zvol. Failing to use GFP_ATOMIC permits them to
block under memory pressure, which can prevent swap operations and cause
deadlocks. We use GFP_ATOMIC | __GFP_HIGH for these allocations because
they are required for swap operations on zvols.

Signed-off-by: Richard Yao <ryao@cs.stonybrook.edu>
  • Loading branch information
ryao committed Jul 3, 2013
1 parent 294f680 commit 8f157ab
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 3 deletions.
2 changes: 1 addition & 1 deletion module/zfs/dmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,7 @@ dmu_bio_clone(struct bio *bio, struct bio **bio_copy)
return EINVAL;

while (bio) {
bio_new = bio_clone(bio, GFP_NOIO);
bio_new = bio_clone(bio, GFP_ATOMIC | __GFP_HIGH);
if (bio_new == NULL) {
dmu_bio_put(bio_root);
return ENOMEM;
Expand Down
4 changes: 2 additions & 2 deletions module/zfs/vdev_disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ __vdev_disk_physio(struct block_device *bdev, zio_t *zio, caddr_t kbuf_ptr,
goto retry;
}

dr->dr_bio[i] = bio_alloc(GFP_NOIO,
dr->dr_bio[i] = bio_alloc(GFP_ATOMIC | __GFP_HIGH,
bio_nr_pages(bio_ptr, bio_size));
if (dr->dr_bio[i] == NULL) {
vdev_disk_dio_free(dr);
Expand Down Expand Up @@ -632,7 +632,7 @@ vdev_disk_io_flush(struct block_device *bdev, zio_t *zio)
if (!q)
return ENXIO;

bio = bio_alloc(GFP_KERNEL, 0);
bio = bio_alloc(GFP_ATOMIC | __GFP_HIGH, 0);
if (!bio)
return ENOMEM;

Expand Down

0 comments on commit 8f157ab

Please sign in to comment.