lkml.org 
[lkml]   [2020]   [May]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.6 004/194] xprtrdma: Fix trace point use-after-free race
    Date
    From: Chuck Lever <chuck.lever@oracle.com>

    [ Upstream commit bdb2ce82818577ba6e57b7d68b698b8d17329281 ]

    It's not safe to use resources pointed to by the @send_wr of
    ib_post_send() _after_ that function returns. Those resources are
    typically freed by the Send completion handler, which can run before
    ib_post_send() returns.

    Thus the trace points currently around ib_post_send() in the
    client's RPC/RDMA transport are a hazard, even when they are
    disabled. Rearrange them so that they touch the Work Request only
    _before_ ib_post_send() is invoked.

    Fixes: ab03eff58eb5 ("xprtrdma: Add trace points in RPC Call transmit paths")
    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>
    ---
    include/trace/events/rpcrdma.h | 12 ++++--------
    net/sunrpc/xprtrdma/verbs.c | 2 +-
    2 files changed, 5 insertions(+), 9 deletions(-)

    diff --git a/include/trace/events/rpcrdma.h b/include/trace/events/rpcrdma.h
    index fa14adf242353..43158151821c4 100644
    --- a/include/trace/events/rpcrdma.h
    +++ b/include/trace/events/rpcrdma.h
    @@ -721,11 +721,10 @@ TRACE_EVENT(xprtrdma_prepsend_failed,

    TRACE_EVENT(xprtrdma_post_send,
    TP_PROTO(
    - const struct rpcrdma_req *req,
    - int status
    + const struct rpcrdma_req *req
    ),

    - TP_ARGS(req, status),
    + TP_ARGS(req),

    TP_STRUCT__entry(
    __field(const void *, req)
    @@ -734,7 +733,6 @@ TRACE_EVENT(xprtrdma_post_send,
    __field(unsigned int, client_id)
    __field(int, num_sge)
    __field(int, signaled)
    - __field(int, status)
    ),

    TP_fast_assign(
    @@ -747,15 +745,13 @@ TRACE_EVENT(xprtrdma_post_send,
    __entry->sc = req->rl_sendctx;
    __entry->num_sge = req->rl_wr.num_sge;
    __entry->signaled = req->rl_wr.send_flags & IB_SEND_SIGNALED;
    - __entry->status = status;
    ),

    - TP_printk("task:%u@%u req=%p sc=%p (%d SGE%s) %sstatus=%d",
    + TP_printk("task:%u@%u req=%p sc=%p (%d SGE%s) %s",
    __entry->task_id, __entry->client_id,
    __entry->req, __entry->sc, __entry->num_sge,
    (__entry->num_sge == 1 ? "" : "s"),
    - (__entry->signaled ? "signaled " : ""),
    - __entry->status
    + (__entry->signaled ? "signaled" : "")
    )
    );

    diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
    index 4b9fbf69b4955..a48b99f3682c3 100644
    --- a/net/sunrpc/xprtrdma/verbs.c
    +++ b/net/sunrpc/xprtrdma/verbs.c
    @@ -1523,8 +1523,8 @@ int rpcrdma_post_sends(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
    --ep->rep_send_count;
    }

    + trace_xprtrdma_post_send(req);
    rc = frwr_send(r_xprt, req);
    - trace_xprtrdma_post_send(req, rc);
    if (rc)
    return -ENOTCONN;
    return 0;
    --
    2.20.1


    \
     
     \ /
      Last update: 2020-05-18 20:14    [W:4.151 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site