lkml.org 
[lkml]   [2016]   [Feb]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.13.y-ckt 103/136] IB/qib: fix mcast detach when qp not attached
    Date
    3.13.11-ckt34 -stable review patch.  If anyone has any objections, please let me know.

    ---8<------------------------------------------------------------

    From: Mike Marciniszyn <mike.marciniszyn@intel.com>

    commit 09dc9cd6528f5b52bcbd3292a6312e762c85260f upstream.

    The code produces the following trace:

    [1750924.419007] general protection fault: 0000 [#3] SMP
    [1750924.420364] Modules linked in: nfnetlink autofs4 rpcsec_gss_krb5 nfsv4
    dcdbas rfcomm bnep bluetooth nfsd auth_rpcgss nfs_acl dm_multipath nfs lockd
    scsi_dh sunrpc fscache radeon ttm drm_kms_helper drm serio_raw parport_pc
    ppdev i2c_algo_bit lpc_ich ipmi_si ib_mthca ib_qib dca lp parport ib_ipoib
    mac_hid ib_cm i3000_edac ib_sa ib_uverbs edac_core ib_umad ib_mad ib_core
    ib_addr tg3 ptp dm_mirror dm_region_hash dm_log psmouse pps_core
    [1750924.420364] CPU: 1 PID: 8401 Comm: python Tainted: G D
    3.13.0-39-generic #66-Ubuntu
    [1750924.420364] Hardware name: Dell Computer Corporation PowerEdge
    860/0XM089, BIOS A04 07/24/2007
    [1750924.420364] task: ffff8800366a9800 ti: ffff88007af1c000 task.ti:
    ffff88007af1c000
    [1750924.420364] RIP: 0010:[<ffffffffa0131d51>] [<ffffffffa0131d51>]
    qib_mcast_qp_free+0x11/0x50 [ib_qib]
    [1750924.420364] RSP: 0018:ffff88007af1dd70 EFLAGS: 00010246
    [1750924.420364] RAX: 0000000000000001 RBX: ffff88007b822688 RCX:
    000000000000000f
    [1750924.420364] RDX: ffff88007b822688 RSI: ffff8800366c15a0 RDI:
    6764697200000000
    [1750924.420364] RBP: ffff88007af1dd78 R08: 0000000000000001 R09:
    0000000000000000
    [1750924.420364] R10: 0000000000000011 R11: 0000000000000246 R12:
    ffff88007baa1d98
    [1750924.420364] R13: ffff88003ecab000 R14: ffff88007b822660 R15:
    0000000000000000
    [1750924.420364] FS: 00007ffff7fd8740(0000) GS:ffff88007fc80000(0000)
    knlGS:0000000000000000
    [1750924.420364] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [1750924.420364] CR2: 00007ffff597c750 CR3: 000000006860b000 CR4:
    00000000000007e0
    [1750924.420364] Stack:
    [1750924.420364] ffff88007b822688 ffff88007af1ddf0 ffffffffa0132429
    000000007af1de20
    [1750924.420364] ffff88007baa1dc8 ffff88007baa0000 ffff88007af1de70
    ffffffffa00cb313
    [1750924.420364] 00007fffffffde88 0000000000000000 0000000000000008
    ffff88003ecab000
    [1750924.420364] Call Trace:
    [1750924.420364] [<ffffffffa0132429>] qib_multicast_detach+0x1e9/0x350
    [ib_qib]
    [1750924.568035] [<ffffffffa00cb313>] ? ib_uverbs_modify_qp+0x323/0x3d0
    [ib_uverbs]
    [1750924.568035] [<ffffffffa0092d61>] ib_detach_mcast+0x31/0x50 [ib_core]
    [1750924.568035] [<ffffffffa00cc213>] ib_uverbs_detach_mcast+0x93/0x170
    [ib_uverbs]
    [1750924.568035] [<ffffffffa00c61f6>] ib_uverbs_write+0xc6/0x2c0 [ib_uverbs]
    [1750924.568035] [<ffffffff81312e68>] ? apparmor_file_permission+0x18/0x20
    [1750924.568035] [<ffffffff812d4cd3>] ? security_file_permission+0x23/0xa0
    [1750924.568035] [<ffffffff811bd214>] vfs_write+0xb4/0x1f0
    [1750924.568035] [<ffffffff811bdc49>] SyS_write+0x49/0xa0
    [1750924.568035] [<ffffffff8172f7ed>] system_call_fastpath+0x1a/0x1f
    [1750924.568035] Code: 66 2e 0f 1f 84 00 00 00 00 00 31 c0 5d c3 66 2e 0f 1f
    84 00 00 00 00 00 66 90 0f 1f 44 00 00 55 48 89 e5 53 48 89 fb 48 8b 7f 10
    <f0> ff 8f 40 01 00 00 74 0e 48 89 df e8 8e f8 06 e1 5b 5d c3 0f
    [1750924.568035] RIP [<ffffffffa0131d51>] qib_mcast_qp_free+0x11/0x50
    [ib_qib]
    [1750924.568035] RSP <ffff88007af1dd70>
    [1750924.650439] ---[ end trace 73d5d4b3f8ad4851 ]

    The fix is to note the qib_mcast_qp that was found. If none is found, then
    return EINVAL indicating the error.

    Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
    Reported-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
    Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
    Signed-off-by: Doug Ledford <dledford@redhat.com>
    Signed-off-by: Kamal Mostafa <kamal@canonical.com>
    ---
    drivers/infiniband/hw/qib/qib_verbs_mcast.c | 35 +++++++++++++----------------
    1 file changed, 15 insertions(+), 20 deletions(-)

    diff --git a/drivers/infiniband/hw/qib/qib_verbs_mcast.c b/drivers/infiniband/hw/qib/qib_verbs_mcast.c
    index dabb697..48ba1c3 100644
    --- a/drivers/infiniband/hw/qib/qib_verbs_mcast.c
    +++ b/drivers/infiniband/hw/qib/qib_verbs_mcast.c
    @@ -286,15 +286,13 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
    struct qib_ibdev *dev = to_idev(ibqp->device);
    struct qib_ibport *ibp = to_iport(ibqp->device, qp->port_num);
    struct qib_mcast *mcast = NULL;
    - struct qib_mcast_qp *p, *tmp;
    + struct qib_mcast_qp *p, *tmp, *delp = NULL;
    struct rb_node *n;
    int last = 0;
    int ret;

    - if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET) {
    - ret = -EINVAL;
    - goto bail;
    - }
    + if (ibqp->qp_num <= 1 || qp->state == IB_QPS_RESET)
    + return -EINVAL;

    spin_lock_irq(&ibp->lock);

    @@ -303,8 +301,7 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
    while (1) {
    if (n == NULL) {
    spin_unlock_irq(&ibp->lock);
    - ret = -EINVAL;
    - goto bail;
    + return -EINVAL;
    }

    mcast = rb_entry(n, struct qib_mcast, rb_node);
    @@ -328,6 +325,7 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
    */
    list_del_rcu(&p->list);
    mcast->n_attached--;
    + delp = p;

    /* If this was the last attached QP, remove the GID too. */
    if (list_empty(&mcast->qp_list)) {
    @@ -338,15 +336,16 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
    }

    spin_unlock_irq(&ibp->lock);
    + /* QP not attached */
    + if (!delp)
    + return -EINVAL;
    + /*
    + * Wait for any list walkers to finish before freeing the
    + * list element.
    + */
    + wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1);
    + qib_mcast_qp_free(delp);

    - if (p) {
    - /*
    - * Wait for any list walkers to finish before freeing the
    - * list element.
    - */
    - wait_event(mcast->wait, atomic_read(&mcast->refcount) <= 1);
    - qib_mcast_qp_free(p);
    - }
    if (last) {
    atomic_dec(&mcast->refcount);
    wait_event(mcast->wait, !atomic_read(&mcast->refcount));
    @@ -355,11 +354,7 @@ int qib_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid)
    dev->n_mcast_grps_allocated--;
    spin_unlock_irq(&dev->n_mcast_grps_lock);
    }
    -
    - ret = 0;
    -
    -bail:
    - return ret;
    + return 0;
    }

    int qib_mcast_tree_empty(struct qib_ibport *ibp)
    --
    1.9.1
    \
     
     \ /
      Last update: 2016-02-02 20:01    [W:4.067 / U:0.176 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site