* [PATCH 0/6] Handle bio_alloc failure
@ 2009-04-14 11:06 Nikanth Karthikesan
2009-04-14 11:18 ` Jens Axboe
0 siblings, 1 reply; 9+ messages in thread
From: Nikanth Karthikesan @ 2009-04-14 11:06 UTC (permalink / raw)
To: Jens Axboe
Cc: Neil Brown, linux-kernel, Chris Mason, Andrew Morton,
Dave Kleikamp, xfs-masters
Hi Jens
Some of the callers of bio_alloc() assume that it will never fail and always
return bios. But it can fail. This patch set changes those callers to take
action when bio_alloc() fails.
Thanks
Nikanth
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/6] Handle bio_alloc failure
2009-04-14 11:06 [PATCH 0/6] Handle bio_alloc failure Nikanth Karthikesan
@ 2009-04-14 11:18 ` Jens Axboe
2009-04-14 11:41 ` Nikanth Karthikesan
0 siblings, 1 reply; 9+ messages in thread
From: Jens Axboe @ 2009-04-14 11:18 UTC (permalink / raw)
To: Nikanth Karthikesan
Cc: Neil Brown, linux-kernel, Chris Mason, Andrew Morton,
Dave Kleikamp, xfs-masters
On Tue, Apr 14 2009, Nikanth Karthikesan wrote:
> Hi Jens
>
> Some of the callers of bio_alloc() assume that it will never fail and always
> return bios. But it can fail. This patch set changes those callers to take
> action when bio_alloc() fails.
It will not fail as long as __GFP_WAIT is set, which it is for all 6 of
your patches.
--
Jens Axboe
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/6] Handle bio_alloc failure
2009-04-14 11:18 ` Jens Axboe
@ 2009-04-14 11:41 ` Nikanth Karthikesan
2009-04-14 18:16 ` Theodore Tso
0 siblings, 1 reply; 9+ messages in thread
From: Nikanth Karthikesan @ 2009-04-14 11:41 UTC (permalink / raw)
To: Jens Axboe
Cc: Neil Brown, linux-kernel, Chris Mason, Andrew Morton,
Dave Kleikamp, xfs-masters
On Tuesday 14 April 2009 16:48:38 Jens Axboe wrote:
> On Tue, Apr 14 2009, Nikanth Karthikesan wrote:
> > Hi Jens
> >
> > Some of the callers of bio_alloc() assume that it will never fail and
> > always return bios. But it can fail. This patch set changes those callers
> > to take action when bio_alloc() fails.
>
> It will not fail as long as __GFP_WAIT is set, which it is for all 6 of
> your patches.
I thought so, but was confused by various places where it was being handled!
Can this be merged then?
Thanks
Nikanth
bio_alloc() will not fail as long as __GFP_WAIT is set. __GFP_WAIT is also set
as part of GFP_KERNEL, GFP_NOIO and GFP_NOFS. Remove unnecessary code to
handle bio_alloc failure in those cases.
Signed-off-by: Nikanth Karthikesan <knikanth@suse.de>
---
diff --git a/block/blk-barrier.c b/block/blk-barrier.c
index f7dae57..20b4111 100644
--- a/block/blk-barrier.c
+++ b/block/blk-barrier.c
@@ -319,9 +319,6 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
return -ENXIO;
bio = bio_alloc(GFP_KERNEL, 0);
- if (!bio)
- return -ENOMEM;
-
bio->bi_end_io = bio_end_empty_barrier;
bio->bi_private = &wait;
bio->bi_bdev = bdev;
diff --git a/block/ioctl.c b/block/ioctl.c
index 0f22e62..ad474d4 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -146,8 +146,6 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,
struct bio *bio;
bio = bio_alloc(GFP_KERNEL, 0);
- if (!bio)
- return -ENOMEM;
bio->bi_end_io = blk_ioc_discard_endio;
bio->bi_bdev = bdev;
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index ddae808..a3659c1 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -636,8 +636,6 @@ static int loop_switch(struct loop_device *lo, struct file *file)
{
struct switch_request w;
struct bio *bio = bio_alloc(GFP_KERNEL, 0);
- if (!bio)
- return -ENOMEM;
init_completion(&w.wait);
w.file = file;
bio->bi_private = &w;
diff --git a/fs/direct-io.c b/fs/direct-io.c
index da258e7..05763bb 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -307,8 +307,6 @@ dio_bio_alloc(struct dio *dio, struct block_device *bdev,
struct bio *bio;
bio = bio_alloc(GFP_KERNEL, nr_vecs);
- if (bio == NULL)
- return -ENOMEM;
bio->bi_bdev = bdev;
bio->bi_sector = first_sector;
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
index ba8d9fa..ee1f438 100644
--- a/fs/exofs/inode.c
+++ b/fs/exofs/inode.c
@@ -97,15 +97,10 @@ static int pcol_try_alloc(struct page_collect *pcol)
{
int pages = min_t(unsigned, pcol->expected_pages, BIO_MAX_PAGES);
- for (; pages; pages >>= 1) {
+ if (pages)
pcol->bio = bio_alloc(GFP_KERNEL, pages);
- if (likely(pcol->bio))
- return 0;
- }
- EXOFS_ERR("Failed to kcalloc expected_pages=%u\n",
- pcol->expected_pages);
- return -ENOMEM;
+ return 0;
}
static void pcol_free(struct page_collect *pcol)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 6132353..2a1cb09 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2416,8 +2416,6 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex)
len = ee_len;
bio = bio_alloc(GFP_NOIO, len);
- if (!bio)
- return -ENOMEM;
bio->bi_sector = ee_pblock;
bio->bi_bdev = inode->i_sb->s_bdev;
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 51883b3..650a730 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -272,11 +272,6 @@ static int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector)
lock_page(page);
bio = bio_alloc(GFP_NOFS, 1);
- if (unlikely(!bio)) {
- __free_page(page);
- return -ENOBUFS;
- }
-
bio->bi_sector = sector * (sb->s_blocksize >> 9);
bio->bi_bdev = sb->s_bdev;
bio_add_page(bio, page, PAGE_SIZE, 0);
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 7ec89fc..fb4f516 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -421,10 +421,7 @@ xfs_alloc_ioend_bio(
struct bio *bio;
int nvecs = bio_get_nr_vecs(bh->b_bdev);
- do {
- bio = bio_alloc(GFP_NOIO, nvecs);
- nvecs >>= 1;
- } while (!bio);
+ bio = bio_alloc(GFP_NOIO, nvecs);
ASSERT(bio->bi_private == NULL);
bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
index 505f319..8ba052c 100644
--- a/kernel/power/swap.c
+++ b/kernel/power/swap.c
@@ -64,8 +64,6 @@ static int submit(int rw, pgoff_t page_off, struct page *page,
struct bio *bio;
bio = bio_alloc(__GFP_WAIT | __GFP_HIGH, 1);
- if (!bio)
- return -ENOMEM;
bio->bi_sector = page_off * (PAGE_SIZE >> 9);
bio->bi_bdev = resume_bdev;
bio->bi_end_io = end_swap_bio_read;
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 0/6] Handle bio_alloc failure
2009-04-14 11:41 ` Nikanth Karthikesan
@ 2009-04-14 18:16 ` Theodore Tso
2009-04-14 18:20 ` Jens Axboe
2009-04-14 18:46 ` Andrew Morton
0 siblings, 2 replies; 9+ messages in thread
From: Theodore Tso @ 2009-04-14 18:16 UTC (permalink / raw)
To: Nikanth Karthikesan
Cc: Jens Axboe, Neil Brown, linux-kernel, Chris Mason, Andrew Morton,
Dave Kleikamp, xfs-masters
On Tue, Apr 14, 2009 at 05:11:19PM +0530, Nikanth Karthikesan wrote:
> On Tuesday 14 April 2009 16:48:38 Jens Axboe wrote:
> >
> > It will not fail as long as __GFP_WAIT is set, which it is for all 6 of
> > your patches.
Um, before we take out the checks, can we please make sure this is a
guaranteed, documented behaviour? In include/linux/page_alloc.h,
__GFP_NOFAIL is documented as "will never fail", but it says
absolutely nothing about __GFP_WAIT.
Some day, someone will create a static checker that will flag warnings
when people fail to check for allocation failures, and it would be
good if the formal semantics for __GFP_WAIT, and hence for GFP_NOFS,
GFP_KERNEL, and GFP_USER, et. al. are defined.
We have code in fs/jbd2/transaction.c that calls kzalloc with
GFP_NOFS|__GFP_NOFAIL, since I and many other people had the
assumption that without __GFP_NOFAIL, an GFP_NOFS allocation could
very well fail.
Or is this special-case behaviour which bio_alloc() guarantees, but
not necessarily any other allocation function?
- Ted
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/6] Handle bio_alloc failure
2009-04-14 18:16 ` Theodore Tso
@ 2009-04-14 18:20 ` Jens Axboe
2009-04-14 18:33 ` Theodore Tso
2009-04-14 18:46 ` Andrew Morton
1 sibling, 1 reply; 9+ messages in thread
From: Jens Axboe @ 2009-04-14 18:20 UTC (permalink / raw)
To: Theodore Tso
Cc: Nikanth Karthikesan, Neil Brown, linux-kernel, Chris Mason,
Andrew Morton, Dave Kleikamp, xfs-masters
On Tue, Apr 14 2009, Theodore Tso wrote:
> On Tue, Apr 14, 2009 at 05:11:19PM +0530, Nikanth Karthikesan wrote:
> > On Tuesday 14 April 2009 16:48:38 Jens Axboe wrote:
> > >
> > > It will not fail as long as __GFP_WAIT is set, which it is for all 6 of
> > > your patches.
>
> Um, before we take out the checks, can we please make sure this is a
> guaranteed, documented behaviour? In include/linux/page_alloc.h,
> __GFP_NOFAIL is documented as "will never fail", but it says
> absolutely nothing about __GFP_WAIT.
>
> Some day, someone will create a static checker that will flag warnings
> when people fail to check for allocation failures, and it would be
> good if the formal semantics for __GFP_WAIT, and hence for GFP_NOFS,
> GFP_KERNEL, and GFP_USER, et. al. are defined.
>
> We have code in fs/jbd2/transaction.c that calls kzalloc with
> GFP_NOFS|__GFP_NOFAIL, since I and many other people had the
> assumption that without __GFP_NOFAIL, an GFP_NOFS allocation could
> very well fail.
>
> Or is this special-case behaviour which bio_alloc() guarantees, but
> not necessarily any other allocation function?
It's a bio_alloc() guarantee, it uses a mempool backing. And if you use
a mempool backing, any allocation that can wait will always be
satisfied.
--
Jens Axboe
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/6] Handle bio_alloc failure
2009-04-14 18:20 ` Jens Axboe
@ 2009-04-14 18:33 ` Theodore Tso
2009-04-14 18:40 ` Jens Axboe
0 siblings, 1 reply; 9+ messages in thread
From: Theodore Tso @ 2009-04-14 18:33 UTC (permalink / raw)
To: Jens Axboe
Cc: Nikanth Karthikesan, Neil Brown, linux-kernel, Chris Mason,
Andrew Morton, Dave Kleikamp, xfs-masters
On Tue, Apr 14, 2009 at 08:20:49PM +0200, Jens Axboe wrote:
>
> It's a bio_alloc() guarantee, it uses a mempool backing. And if you use
> a mempool backing, any allocation that can wait will always be
> satisfied.
>
Am I missing something? I don't see anything in
include/linux/mempool.h or mm/mempool.c, or in block/blk-core.c or
include/linux/bio.h which documents that GFP_WAIT implies that
bio_alloc() will always succeed.
My concern is that at some point in the future, someone either in the
block device layer or in mm/mempool.c will consider this an
implementation detail, and all of sudden calls to bio_alloc() with
GFP_WAIT will start failing and the resulting hilarty which ensues
won't be easily predicted by the developer making this change.
Regards,
- Ted
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/6] Handle bio_alloc failure
2009-04-14 18:33 ` Theodore Tso
@ 2009-04-14 18:40 ` Jens Axboe
0 siblings, 0 replies; 9+ messages in thread
From: Jens Axboe @ 2009-04-14 18:40 UTC (permalink / raw)
To: Theodore Tso
Cc: Nikanth Karthikesan, Neil Brown, linux-kernel, Chris Mason,
Andrew Morton, Dave Kleikamp, xfs-masters
On Tue, Apr 14 2009, Theodore Tso wrote:
> On Tue, Apr 14, 2009 at 08:20:49PM +0200, Jens Axboe wrote:
> >
> > It's a bio_alloc() guarantee, it uses a mempool backing. And if you use
> > a mempool backing, any allocation that can wait will always be
> > satisfied.
> >
>
> Am I missing something? I don't see anything in
> include/linux/mempool.h or mm/mempool.c, or in block/blk-core.c or
> include/linux/bio.h which documents that GFP_WAIT implies that
> bio_alloc() will always succeed.
Read mempool.c:mempool_alloc(). If __GFP_WAIT is set, it'll never turn
without having done the allocation. It's a bit weird that it isn't
documented in bio_alloc() itself, but there are several other places in
bio.c that references the fact that it cannot fail.
> My concern is that at some point in the future, someone either in the
> block device layer or in mm/mempool.c will consider this an
> implementation detail, and all of sudden calls to bio_alloc() with
> GFP_WAIT will start failing and the resulting hilarty which ensues
> won't be easily predicted by the developer making this change.
It's the entire premise of a mempool, so trust me, it'll never go away.
It is the reason they were added in the first place, for eg swap you
need the mempool guarantee or you risk deadlocking.
--
Jens Axboe
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/6] Handle bio_alloc failure
2009-04-14 18:16 ` Theodore Tso
2009-04-14 18:20 ` Jens Axboe
@ 2009-04-14 18:46 ` Andrew Morton
2009-04-15 8:46 ` Nick Piggin
1 sibling, 1 reply; 9+ messages in thread
From: Andrew Morton @ 2009-04-14 18:46 UTC (permalink / raw)
To: Theodore Tso
Cc: knikanth, jens.axboe, neilb, linux-kernel, chris.mason, shaggy,
xfs-masters
On Tue, 14 Apr 2009 14:16:32 -0400
Theodore Tso <tytso@mit.edu> wrote:
> In include/linux/page_alloc.h,
> __GFP_NOFAIL is documented as "will never fail", but it says
> absolutely nothing about __GFP_WAIT.
In the present implementation, a __GFP_WAIT allocation for order <=3
will only fail if the caller was oom-killed.
Which raises the question "what happens when a mempool_alloc() caller
gets oom-killed?".
Seems that it will loop around in mempool_alloc() doing weak attempts
to allocate memory, not doing direct reclaim while waiting for someone
else to free something up. hm. I guess it'll recover eventually.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/6] Handle bio_alloc failure
2009-04-14 18:46 ` Andrew Morton
@ 2009-04-15 8:46 ` Nick Piggin
0 siblings, 0 replies; 9+ messages in thread
From: Nick Piggin @ 2009-04-15 8:46 UTC (permalink / raw)
To: Andrew Morton
Cc: Theodore Tso, knikanth, jens.axboe, neilb, linux-kernel,
chris.mason, shaggy, xfs-masters
On Wednesday 15 April 2009 04:46:04 Andrew Morton wrote:
> On Tue, 14 Apr 2009 14:16:32 -0400
> Theodore Tso <tytso@mit.edu> wrote:
>
> > In include/linux/page_alloc.h,
> > __GFP_NOFAIL is documented as "will never fail", but it says
> > absolutely nothing about __GFP_WAIT.
>
> In the present implementation, a __GFP_WAIT allocation for order <=3
> will only fail if the caller was oom-killed.
>
> Which raises the question "what happens when a mempool_alloc() caller
> gets oom-killed?".
>
> Seems that it will loop around in mempool_alloc() doing weak attempts
> to allocate memory, not doing direct reclaim while waiting for someone
> else to free something up. hm. I guess it'll recover eventually.
Yes, it doesn't have to reclaim anything (quite likely if we've
been OOM killed, reclaim is very difficult or impossible at this
point anyway). It will recover when an object gets returned to
the mempool by someone else. No point in using page allocator
reserve when we have guaranteed forward progress anyway.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2009-04-15 8:46 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-14 11:06 [PATCH 0/6] Handle bio_alloc failure Nikanth Karthikesan
2009-04-14 11:18 ` Jens Axboe
2009-04-14 11:41 ` Nikanth Karthikesan
2009-04-14 18:16 ` Theodore Tso
2009-04-14 18:20 ` Jens Axboe
2009-04-14 18:33 ` Theodore Tso
2009-04-14 18:40 ` Jens Axboe
2009-04-14 18:46 ` Andrew Morton
2009-04-15 8:46 ` Nick Piggin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox