IB/cm: Fix sleeping in atomic when RoCE is used
authorRoland Dreier <roland@purestorage.com>
Tue, 29 Aug 2017 17:34:43 +0000 (10:34 -0700)
committerDoug Ledford <dledford@redhat.com>
Thu, 31 Aug 2017 12:35:07 +0000 (08:35 -0400)
commitc76161181193985087cd716fdf69b5cb6cf9ee85
treeabc2e8648e24f498f3d768b8a9131866a32cb300
parentf43dbebfa32041826299bdccae0352887fa007ea
IB/cm: Fix sleeping in atomic when RoCE is used

A couple of places in the CM do

    spin_lock_irq(&cm_id_priv->lock);
    ...
    if (cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg))

However when the underlying transport is RoCE, this leads to a sleeping function
being called with the lock held - the callchain is

    cm_alloc_response_msg() ->
      ib_create_ah_from_wc() ->
        ib_init_ah_from_wc() ->
          rdma_addr_find_l2_eth_by_grh() ->
            rdma_resolve_ip()

and rdma_resolve_ip() starts out by doing

    req = kzalloc(sizeof *req, GFP_KERNEL);

not to mention rdma_addr_find_l2_eth_by_grh() doing

    wait_for_completion(&ctx.comp);

to wait for the task that rdma_resolve_ip() queues up.

Fix this by moving the AH creation out of the lock.

Signed-off-by: Roland Dreier <roland@purestorage.com>
Reviewed-by: Sean Hefty <sean.hefty@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/core/cm.c