Commit 5be8e6a2 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ramdisk memory allocation fixes

Allocating pagecache pages within the disk request_fn is deadlocky and prone
to page allocation failures, causing write I/O errors.

Attempt to improve things by fiddling with gfp masks.
parent a16539ba
...@@ -319,18 +319,39 @@ static int rd_open(struct inode *inode, struct file *filp) ...@@ -319,18 +319,39 @@ static int rd_open(struct inode *inode, struct file *filp)
{ {
unsigned unit = iminor(inode); unsigned unit = iminor(inode);
/*
* Immunize device against invalidate_buffers() and prune_icache().
*/
if (rd_bdev[unit] == NULL) { if (rd_bdev[unit] == NULL) {
struct block_device *bdev = inode->i_bdev; struct block_device *bdev = inode->i_bdev;
struct address_space *mapping;
int gfp_mask;
inode = igrab(bdev->bd_inode); inode = igrab(bdev->bd_inode);
rd_bdev[unit] = bdev; rd_bdev[unit] = bdev;
bdev->bd_openers++; bdev->bd_openers++;
bdev->bd_block_size = rd_blocksize; bdev->bd_block_size = rd_blocksize;
inode->i_size = get_capacity(rd_disks[unit])<<9; inode->i_size = get_capacity(rd_disks[unit])<<9;
inode->i_mapping->a_ops = &ramdisk_aops; mapping = inode->i_mapping;
inode->i_mapping->backing_dev_info = &rd_backing_dev_info; mapping->a_ops = &ramdisk_aops;
mapping->backing_dev_info = &rd_backing_dev_info;
/*
* Deep badness. rd_blkdev_pagecache_IO() needs to allocate
* pagecache pages within a request_fn. We cannot recur back
* into the filesytem which is mounted atop the ramdisk, because
* that would deadlock on fs locks. And we really don't want
* to reenter rd_blkdev_pagecache_IO when we're already within
* that function.
*
* So we turn off __GFP_FS and __GFP_IO.
*
* And to give this thing a hope of working, turn on __GFP_HIGH.
* Hopefully, there's enough regular memory allocation going on
* for the page allocator emergency pools to keep the ramdisk
* driver happy.
*/
gfp_mask = mapping_gfp_mask(mapping);
gfp_mask &= ~(__GFP_FS|__GFP_IO);
gfp_mask |= __GFP_HIGH;
mapping_set_gfp_mask(mapping, gfp_mask);
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment