lkml.org 
[lkml]   [2020]   [Jan]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 476/639] xdp: fix possible cq entry leak
    Date
    From: Ilya Maximets <i.maximets@samsung.com>

    [ Upstream commit 675716400da6f15b9d3db04ef74ee74ca9a00af3 ]

    Completion queue address reservation could not be undone.
    In case of bad 'queue_id' or skb allocation failure, reserved entry
    will be leaked reducing the total capacity of completion queue.

    Fix that by moving reservation to the point where failure is not
    possible. Additionally, 'queue_id' checking moved out from the loop
    since there is no point to check it there.

    Fixes: 35fcde7f8deb ("xsk: support for Tx")
    Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
    Acked-by: Björn Töpel <bjorn.topel@intel.com>
    Tested-by: William Tu <u9012063@gmail.com>
    Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    net/xdp/xsk.c | 11 ++++-------
    1 file changed, 4 insertions(+), 7 deletions(-)

    diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
    index 547fc4554b22c..c90854bc3048e 100644
    --- a/net/xdp/xsk.c
    +++ b/net/xdp/xsk.c
    @@ -218,6 +218,9 @@ static int xsk_generic_xmit(struct sock *sk, struct msghdr *m,

    mutex_lock(&xs->mutex);

    + if (xs->queue_id >= xs->dev->real_num_tx_queues)
    + goto out;
    +
    while (xskq_peek_desc(xs->tx, &desc)) {
    char *buffer;
    u64 addr;
    @@ -228,12 +231,6 @@ static int xsk_generic_xmit(struct sock *sk, struct msghdr *m,
    goto out;
    }

    - if (xskq_reserve_addr(xs->umem->cq))
    - goto out;
    -
    - if (xs->queue_id >= xs->dev->real_num_tx_queues)
    - goto out;
    -
    len = desc.len;
    skb = sock_alloc_send_skb(sk, len, 1, &err);
    if (unlikely(!skb)) {
    @@ -245,7 +242,7 @@ static int xsk_generic_xmit(struct sock *sk, struct msghdr *m,
    addr = desc.addr;
    buffer = xdp_umem_get_data(xs->umem, addr);
    err = skb_store_bits(skb, 0, buffer, len);
    - if (unlikely(err)) {
    + if (unlikely(err) || xskq_reserve_addr(xs->umem->cq)) {
    kfree_skb(skb);
    goto out;
    }
    --
    2.20.1


    \
     
     \ /
      Last update: 2020-01-24 12:40    [W:2.609 / U:0.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site