Re: [patch v2 1/5] mm: add nofail variants of kmalloc kcalloc and kzalloc
On Wed, 1 Sep 2010, David Rientjes wrote: Add kmalloc_nofail(), kcalloc_nofail(), and kzalloc_nofail(). These functions are equivalent to kmalloc(), kcalloc(), and kzalloc(), respectively, except that they will never return NULL and instead loop forever trying to allocate memory. If the first allocation attempt fails because the page allocator doesn't implicitly loop, a warning will be emitted, including a call trace. Subsequent failures will suppress this warning. These were added as helper functions for documentation and auditability. No future callers should be added. Are there any objections to merging this series through -mm with the exception of the fifth patch for ntfs? That particular patch needs to have its WARN_ON_ONCE() condition rewritten since it fallbacks to vmalloc for high order allocs. Thanks. -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch v2 1/5] mm: add nofail variants of kmalloc kcalloc and kzalloc
On 09/02/2010 03:02 AM, David Rientjes wrote: --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -334,6 +334,57 @@ static inline void *kzalloc_node(size_t size, gfp_t flags, int node) return kmalloc_node(size, flags | __GFP_ZERO, node); } +/** + * kmalloc_nofail - infinitely loop until kmalloc() succeeds. + * @size: how many bytes of memory are required. + * @flags: the type of memory to allocate (see kmalloc). + * + * NOTE: no new callers of this function should be implemented! + * All memory allocations should be failable whenever possible. + */ +static inline void *kmalloc_nofail(size_t size, gfp_t flags) +{ + void *ret; + + for (;;) { + ret = kmalloc(size, flags); + if (ret) + return ret; + WARN_ON_ONCE(get_order(size) PAGE_ALLOC_COSTLY_ORDER); This doesn't work as you expect. kmalloc will warn every time it fails. __GFP_NOFAIL used to disable the warning. Actually what's wrong with __GFP_NOFAIL? I cannot find a reason in the changelogs why the patches are needed. + } -- js -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch v2 1/5] mm: add nofail variants of kmalloc kcalloc and kzalloc
On Thu 02-09-10 09:59:13, Jiri Slaby wrote: On 09/02/2010 03:02 AM, David Rientjes wrote: --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -334,6 +334,57 @@ static inline void *kzalloc_node(size_t size, gfp_t flags, int node) return kmalloc_node(size, flags | __GFP_ZERO, node); } +/** + * kmalloc_nofail - infinitely loop until kmalloc() succeeds. + * @size: how many bytes of memory are required. + * @flags: the type of memory to allocate (see kmalloc). + * + * NOTE: no new callers of this function should be implemented! + * All memory allocations should be failable whenever possible. + */ +static inline void *kmalloc_nofail(size_t size, gfp_t flags) +{ + void *ret; + + for (;;) { +ret = kmalloc(size, flags); + if (ret) + return ret; + WARN_ON_ONCE(get_order(size) PAGE_ALLOC_COSTLY_ORDER); This doesn't work as you expect. kmalloc will warn every time it fails. __GFP_NOFAIL used to disable the warning. Actually what's wrong with __GFP_NOFAIL? I cannot find a reason in the changelogs why the patches are needed. David should probably add the reasoning to the changelogs so that he doesn't have to explain again and again ;). But if I understood it correctly, the concern is that the looping checks slightly impact fast path of the callers which do not need it. Generally, also looping for a long time inside allocator isn't a nice thing but some callers aren't able to do better for now to the patch is imperfect in this sence... Honza -- Jan Kara j...@suse.cz SUSE Labs, CR -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch v2 1/5] mm: add nofail variants of kmalloc kcalloc and kzalloc
On Thu, 2 Sep 2010 16:51:41 +0200 Jan Kara j...@suse.cz wrote: On Thu 02-09-10 09:59:13, Jiri Slaby wrote: On 09/02/2010 03:02 AM, David Rientjes wrote: --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -334,6 +334,57 @@ static inline void *kzalloc_node(size_t size, gfp_t flags, int node) return kmalloc_node(size, flags | __GFP_ZERO, node); } +/** + * kmalloc_nofail - infinitely loop until kmalloc() succeeds. + * @size: how many bytes of memory are required. + * @flags: the type of memory to allocate (see kmalloc). + * + * NOTE: no new callers of this function should be implemented! + * All memory allocations should be failable whenever possible. + */ +static inline void *kmalloc_nofail(size_t size, gfp_t flags) +{ +void *ret; + + for (;;) { + ret = kmalloc(size, flags); + if (ret) + return ret; + WARN_ON_ONCE(get_order(size) PAGE_ALLOC_COSTLY_ORDER); This doesn't work as you expect. kmalloc will warn every time it fails. __GFP_NOFAIL used to disable the warning. Actually what's wrong with __GFP_NOFAIL? I cannot find a reason in the changelogs why the patches are needed. David should probably add the reasoning to the changelogs so that he doesn't have to explain again and again ;). But if I understood it correctly, the concern is that the looping checks slightly impact fast path of the callers which do not need it. Generally, also looping for a long time inside allocator isn't a nice thing but some callers aren't able to do better for now to the patch is imperfect in this sence... I'm actually a bit confused about this too. I thought David said he was removing a branch on the *slow* path - which make sense as you wouldn't even test NOFAIL until you had a failure. Why are branches on the slow-path an issue?? This is an important question to me because I still hope to see the swap-over-nfs patches merged eventually and they add a branch on the slow path (if I remember correctly). NeilBrown -- To unsubscribe from this list: send the line unsubscribe linux-btrfs in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[patch v2 1/5] mm: add nofail variants of kmalloc kcalloc and kzalloc
Add kmalloc_nofail(), kcalloc_nofail(), and kzalloc_nofail(). These functions are equivalent to kmalloc(), kcalloc(), and kzalloc(), respectively, except that they will never return NULL and instead loop forever trying to allocate memory. If the first allocation attempt fails because the page allocator doesn't implicitly loop, a warning will be emitted, including a call trace. Subsequent failures will suppress this warning. These were added as helper functions for documentation and auditability. No future callers should be added. Signed-off-by: David Rientjes rient...@google.com --- drivers/md/dm-region-hash.c |2 +- fs/btrfs/inode.c|2 +- fs/gfs2/log.c |2 +- fs/gfs2/rgrp.c | 18 +-- fs/jbd/transaction.c| 11 ++-- fs/reiserfs/journal.c |3 +- include/linux/slab.h| 51 +++ 7 files changed, 64 insertions(+), 25 deletions(-) diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c --- a/drivers/md/dm-region-hash.c +++ b/drivers/md/dm-region-hash.c @@ -290,7 +290,7 @@ static struct dm_region *__rh_alloc(struct dm_region_hash *rh, region_t region) nreg = mempool_alloc(rh-region_pool, GFP_ATOMIC); if (unlikely(!nreg)) - nreg = kmalloc(sizeof(*nreg), GFP_NOIO | __GFP_NOFAIL); + nreg = kmalloc_nofail(sizeof(*nreg), GFP_NOIO); nreg-state = rh-log-type-in_sync(rh-log, region, 1) ? DM_RH_CLEAN : DM_RH_NOSYNC; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -1967,7 +1967,7 @@ void btrfs_add_delayed_iput(struct inode *inode) if (atomic_add_unless(inode-i_count, -1, 1)) return; - delayed = kmalloc(sizeof(*delayed), GFP_NOFS | __GFP_NOFAIL); + delayed = kmalloc_nofail(sizeof(*delayed), GFP_NOFS); delayed-inode = inode; spin_lock(fs_info-delayed_iput_lock); diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -709,7 +709,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) } trace_gfs2_log_flush(sdp, 1); - ai = kzalloc(sizeof(struct gfs2_ail), GFP_NOFS | __GFP_NOFAIL); + ai = kzalloc_nofail(sizeof(struct gfs2_ail), GFP_NOFS); INIT_LIST_HEAD(ai-ai_ail1_list); INIT_LIST_HEAD(ai-ai_ail2_list); diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1440,8 +1440,8 @@ static struct gfs2_rgrpd *rgblk_free(struct gfs2_sbd *sdp, u64 bstart, rgrp_blk++; if (!bi-bi_clone) { - bi-bi_clone = kmalloc(bi-bi_bh-b_size, - GFP_NOFS | __GFP_NOFAIL); + bi-bi_clone = kmalloc_nofail(bi-bi_bh-b_size, + GFP_NOFS); memcpy(bi-bi_clone + bi-bi_offset, bi-bi_bh-b_data + bi-bi_offset, bi-bi_len); @@ -1759,9 +1759,6 @@ fail: * @block: the block * * Figure out what RG a block belongs to and add that RG to the list - * - * FIXME: Don't use NOFAIL - * */ void gfs2_rlist_add(struct gfs2_sbd *sdp, struct gfs2_rgrp_list *rlist, @@ -1789,8 +1786,8 @@ void gfs2_rlist_add(struct gfs2_sbd *sdp, struct gfs2_rgrp_list *rlist, if (rlist-rl_rgrps == rlist-rl_space) { new_space = rlist-rl_space + 10; - tmp = kcalloc(new_space, sizeof(struct gfs2_rgrpd *), - GFP_NOFS | __GFP_NOFAIL); + tmp = kcalloc_nofail(new_space, sizeof(struct gfs2_rgrpd *), + GFP_NOFS); if (rlist-rl_rgd) { memcpy(tmp, rlist-rl_rgd, @@ -1811,17 +1808,14 @@ void gfs2_rlist_add(struct gfs2_sbd *sdp, struct gfs2_rgrp_list *rlist, * @rlist: the list of resource groups * @state: the lock state to acquire the RG lock in * @flags: the modifier flags for the holder structures - * - * FIXME: Don't use NOFAIL - * */ void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, unsigned int state) { unsigned int x; - rlist-rl_ghs = kcalloc(rlist-rl_rgrps, sizeof(struct gfs2_holder), - GFP_NOFS | __GFP_NOFAIL); + rlist-rl_ghs = kcalloc_nofail(rlist-rl_rgrps, + sizeof(struct gfs2_holder), GFP_NOFS); for (x = 0; x rlist-rl_rgrps; x++) gfs2_holder_init(rlist-rl_rgd[x]-rd_gl, state, 0, diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c @@ -98,14 +98,9 @@ static int start_this_handle(journal_t *journal, handle_t *handle) } alloc_transaction: - if (!journal-j_running_transaction) { - new_transaction =