Skip to content

Commit e89e8d8

Browse files
chuckleveramschuma-ntap
authored andcommitted
xprtrdma: Fix BUG after a device removal
Michal Kalderon reports a BUG that occurs just after device removal: [ 169.112490] rpcrdma: removing device qedr0 for 192.168.110.146:20049 [ 169.143909] BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 [ 169.181837] IP: rpcrdma_dma_unmap_regbuf+0xa/0x60 [rpcrdma] The RPC/RDMA client transport attempts to allocate some resources on demand. Registered buffers are one such resource. These are allocated (or re-allocated) by xprt_rdma_allocate to hold RPC Call and Reply messages. A hardware resource is associated with each of these buffers, as they can be used for a Send or Receive Work Request. If a device is removed from under an NFS/RDMA mount, the transport layer is responsible for releasing all hardware resources before the device can be finally unplugged. A BUG results when the NFS mount hasn't yet seen much activity: the transport tries to release resources that haven't yet been allocated. rpcrdma_free_regbuf() already checks for this case, so just move that check to cover the DEVICE_REMOVAL case as well. Reported-by: Michal Kalderon <[email protected]> Fixes: bebd031 ("xprtrdma: Support unplugging an HCA ...") Signed-off-by: Chuck Lever <[email protected]> Tested-by: Michal Kalderon <[email protected]> Cc: [email protected] # v4.12+ Signed-off-by: Anna Schumaker <[email protected]>
1 parent 1179e2c commit e89e8d8

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

net/sunrpc/xprtrdma/verbs.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,6 +1502,9 @@ __rpcrdma_dma_map_regbuf(struct rpcrdma_ia *ia, struct rpcrdma_regbuf *rb)
15021502
static void
15031503
rpcrdma_dma_unmap_regbuf(struct rpcrdma_regbuf *rb)
15041504
{
1505+
if (!rb)
1506+
return;
1507+
15051508
if (!rpcrdma_regbuf_is_mapped(rb))
15061509
return;
15071510

@@ -1517,9 +1520,6 @@ rpcrdma_dma_unmap_regbuf(struct rpcrdma_regbuf *rb)
15171520
void
15181521
rpcrdma_free_regbuf(struct rpcrdma_regbuf *rb)
15191522
{
1520-
if (!rb)
1521-
return;
1522-
15231523
rpcrdma_dma_unmap_regbuf(rb);
15241524
kfree(rb);
15251525
}

0 commit comments

Comments
 (0)