lkml.org 
[lkml]   [2020]   [Jan]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.4 059/205] xprtrdma: Fix MR list handling
    Date
    From: Chuck Lever <chuck.lever@oracle.com>

    [ Upstream commit c3700780a096fc66467c81076ddf7f3f11d639b5 ]

    Close some holes introduced by commit 6dc6ec9e04c4 ("xprtrdma: Cache
    free MRs in each rpcrdma_req") that could result in list corruption.

    In addition, the result that is tabulated in @count is no longer
    used, so @count is removed.

    Fixes: 6dc6ec9e04c4 ("xprtrdma: Cache free MRs in each rpcrdma_req")
    Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
    Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/sunrpc/xprtrdma/verbs.c | 41 +++++++++++++++++++------------------
    1 file changed, 21 insertions(+), 20 deletions(-)

    diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
    index f4b136504e96..be74ff8f7873 100644
    --- a/net/sunrpc/xprtrdma/verbs.c
    +++ b/net/sunrpc/xprtrdma/verbs.c
    @@ -79,7 +79,6 @@ static void rpcrdma_reqs_reset(struct rpcrdma_xprt *r_xprt);
    static void rpcrdma_reps_destroy(struct rpcrdma_buffer *buf);
    static void rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt);
    static void rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf);
    -static void rpcrdma_mr_free(struct rpcrdma_mr *mr);
    static struct rpcrdma_regbuf *
    rpcrdma_regbuf_alloc(size_t size, enum dma_data_direction direction,
    gfp_t flags);
    @@ -967,7 +966,7 @@ rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt)
    mr->mr_xprt = r_xprt;

    spin_lock(&buf->rb_lock);
    - list_add(&mr->mr_list, &buf->rb_mrs);
    + rpcrdma_mr_push(mr, &buf->rb_mrs);
    list_add(&mr->mr_all, &buf->rb_all_mrs);
    spin_unlock(&buf->rb_lock);
    }
    @@ -1185,10 +1184,19 @@ int rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
    */
    void rpcrdma_req_destroy(struct rpcrdma_req *req)
    {
    + struct rpcrdma_mr *mr;
    +
    list_del(&req->rl_all);

    - while (!list_empty(&req->rl_free_mrs))
    - rpcrdma_mr_free(rpcrdma_mr_pop(&req->rl_free_mrs));
    + while ((mr = rpcrdma_mr_pop(&req->rl_free_mrs))) {
    + struct rpcrdma_buffer *buf = &mr->mr_xprt->rx_buf;
    +
    + spin_lock(&buf->rb_lock);
    + list_del(&mr->mr_all);
    + spin_unlock(&buf->rb_lock);
    +
    + frwr_release_mr(mr);
    + }

    rpcrdma_regbuf_free(req->rl_recvbuf);
    rpcrdma_regbuf_free(req->rl_sendbuf);
    @@ -1196,24 +1204,28 @@ void rpcrdma_req_destroy(struct rpcrdma_req *req)
    kfree(req);
    }

    -static void
    -rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf)
    +/**
    + * rpcrdma_mrs_destroy - Release all of a transport's MRs
    + * @buf: controlling buffer instance
    + *
    + * Relies on caller holding the transport send lock to protect
    + * removing mr->mr_list from req->rl_free_mrs safely.
    + */
    +static void rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf)
    {
    struct rpcrdma_xprt *r_xprt = container_of(buf, struct rpcrdma_xprt,
    rx_buf);
    struct rpcrdma_mr *mr;
    - unsigned int count;

    - count = 0;
    spin_lock(&buf->rb_lock);
    while ((mr = list_first_entry_or_null(&buf->rb_all_mrs,
    struct rpcrdma_mr,
    mr_all)) != NULL) {
    + list_del(&mr->mr_list);
    list_del(&mr->mr_all);
    spin_unlock(&buf->rb_lock);

    frwr_release_mr(mr);
    - count++;
    spin_lock(&buf->rb_lock);
    }
    spin_unlock(&buf->rb_lock);
    @@ -1286,17 +1298,6 @@ void rpcrdma_mr_put(struct rpcrdma_mr *mr)
    rpcrdma_mr_push(mr, &mr->mr_req->rl_free_mrs);
    }

    -static void rpcrdma_mr_free(struct rpcrdma_mr *mr)
    -{
    - struct rpcrdma_xprt *r_xprt = mr->mr_xprt;
    - struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
    -
    - mr->mr_req = NULL;
    - spin_lock(&buf->rb_lock);
    - rpcrdma_mr_push(mr, &buf->rb_mrs);
    - spin_unlock(&buf->rb_lock);
    -}
    -
    /**
    * rpcrdma_buffer_get - Get a request buffer
    * @buffers: Buffer pool from which to obtain a buffer
    --
    2.20.1
    \
     
     \ /
      Last update: 2020-01-16 17:48    [W:4.083 / U:0.220 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site