On Tue, Nov 18, 2014 at 03:23:36PM -0800, Andrew Morton wrote: > On Fri, 14 Nov 2014 09:49:07 +0900 Minchan Kim <minchan@xxxxxxxxxx> wrote: > > > When I tested zram, I found processes got segfaulted. > > The reason was zram_rw_page doesn't make the page dirty > > again when swap write failed, and even it doesn't return > > error by [1]. > > > > If error by zram internal happens, zram_rw_page should return > > non-zero without calling page_endio. > > It causes resubmit the IO with bio so that it ends up calling > > bio->bi_end_io. > > > > The reason is zram could be used for a block device for FS and > > swap, which they uses different bio complete callback, which > > works differently. So, we should rely on the bio I/O complete > > handler rather than zram_bvec_rw itself in case of I/O fail. > > > > This patch fixes the segfault issue as well one [1]'s > > mentioned > > > > ... > > > > --- a/drivers/block/zram/zram_drv.c > > +++ b/drivers/block/zram/zram_drv.c > > @@ -978,12 +978,10 @@ static int zram_rw_page(struct block_device *bdev, sector_t sector, > > out_unlock: > > up_read(&zram->init_lock); > > out: > > - page_endio(page, rw, err); > > + if (unlikely(err)) > > + return err; > > > > - /* > > - * Return 0 prevents I/O fallback trial caused by rw_page fail > > - * and upper layer can handle this IO error via page error. > > - */ > > + page_endio(page, rw, 0); > > return 0; > > Losing the comment makes me sad. The code is somewhat odd-looking. We > should add some words explaining why we're not reporting errors at this > point. Okay. How about this? diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index decca6f161b8..1d7c90d5e0d0 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -975,6 +975,12 @@ static int zram_rw_page(struct block_device *bdev, sector_t sector, err = zram_bvec_rw(zram, &bv, index, offset, rw); out_unlock: up_read(&zram->init_lock); + /* + * If I/O fails, just return error without calling page_endio. + * It causes resubmit the I/O with bio request by rw_page fallback + * and bio I/O complete handler does things to handle the error + * (e.g., set_page_dirty of swap_writepage fail). + */ if (err == 0) page_endio(page, rw, 0); return err; > > -- > To unsubscribe, send a message with 'unsubscribe linux-mm' in > the body to majordomo@xxxxxxxxx. For more info on Linux MM, > see: http://www.linux-mm.org/ . > Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a> -- Kind regards, Minchan Kim -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>