lkml.org 
[lkml]   [2017]   [Sep]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.12 09/22] radix-tree: must check __radix_tree_preload() return value
    Date
    4.12-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Eric Dumazet <edumazet@google.com>

    commit bc9ae2247ac92fd4d962507bafa3afffff6660ff upstream.

    __radix_tree_preload() only disables preemption if no error is returned.

    So we really need to make sure callers always check the return value.

    idr_preload() contract is to always disable preemption, so we need
    to add a missing preempt_disable() if an error happened.

    Similarly, ida_pre_get() only needs to call preempt_enable() in the
    case no error happened.

    Link: http://lkml.kernel.org/r/1504637190.15310.62.camel@edumazet-glaptop3.roam.corp.google.com
    Fixes: 0a835c4f090a ("Reimplement IDR and IDA using the radix tree")
    Fixes: 7ad3d4d85c7a ("ida: Move ida_bitmap to a percpu variable")
    Signed-off-by: Eric Dumazet <edumazet@google.com>
    Cc: Matthew Wilcox <mawilcox@microsoft.com>
    Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    lib/radix-tree.c | 9 +++++----
    1 file changed, 5 insertions(+), 4 deletions(-)

    --- a/lib/radix-tree.c
    +++ b/lib/radix-tree.c
    @@ -463,7 +463,7 @@ radix_tree_node_free(struct radix_tree_n
    * To make use of this facility, the radix tree must be initialised without
    * __GFP_DIRECT_RECLAIM being passed to INIT_RADIX_TREE().
    */
    -static int __radix_tree_preload(gfp_t gfp_mask, unsigned nr)
    +static __must_check int __radix_tree_preload(gfp_t gfp_mask, unsigned nr)
    {
    struct radix_tree_preload *rtp;
    struct radix_tree_node *node;
    @@ -2103,7 +2103,8 @@ EXPORT_SYMBOL(radix_tree_tagged);
    */
    void idr_preload(gfp_t gfp_mask)
    {
    - __radix_tree_preload(gfp_mask, IDR_PRELOAD_SIZE);
    + if (__radix_tree_preload(gfp_mask, IDR_PRELOAD_SIZE))
    + preempt_disable();
    }
    EXPORT_SYMBOL(idr_preload);

    @@ -2117,13 +2118,13 @@ EXPORT_SYMBOL(idr_preload);
    */
    int ida_pre_get(struct ida *ida, gfp_t gfp)
    {
    - __radix_tree_preload(gfp, IDA_PRELOAD_SIZE);
    /*
    * The IDA API has no preload_end() equivalent. Instead,
    * ida_get_new() can return -EAGAIN, prompting the caller
    * to return to the ida_pre_get() step.
    */
    - preempt_enable();
    + if (!__radix_tree_preload(gfp, IDA_PRELOAD_SIZE))
    + preempt_enable();

    if (!this_cpu_read(ida_bitmap)) {
    struct ida_bitmap *bitmap = kmalloc(sizeof(*bitmap), gfp);

    \
     
     \ /
      Last update: 2017-09-12 19:10    [W:3.326 / U:0.232 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site