Skip to content

Commit 99b7650

Browse files
hcleesmfrench
authored andcommitted
ksmbd: smbd: call rdma_accept() under CM handler
if CONFIG_LOCKDEP is enabled, the following kernel warning message is generated because rdma_accept() checks whehter the handler_mutex is held by lockdep_assert_held. CM(Connection Manager) holds the mutex before CM handler callback is called. [ 63.211405 ] WARNING: CPU: 1 PID: 345 at drivers/infiniband/core/cma.c:4405 rdma_accept+0x17a/0x350 [ 63.212080 ] RIP: 0010:rdma_accept+0x17a/0x350 ... [ 63.214036 ] Call Trace: [ 63.214098 ] <TASK> [ 63.214185 ] smb_direct_accept_client+0xb4/0x170 [ksmbd] [ 63.214412 ] smb_direct_prepare+0x322/0x8c0 [ksmbd] [ 63.214555 ] ? rcu_read_lock_sched_held+0x3a/0x70 [ 63.214700 ] ksmbd_conn_handler_loop+0x63/0x270 [ksmbd] [ 63.214826 ] ? ksmbd_conn_alive+0x80/0x80 [ksmbd] [ 63.214952 ] kthread+0x171/0x1a0 [ 63.215039 ] ? set_kthread_struct+0x40/0x40 [ 63.215128 ] ret_from_fork+0x22/0x30 To avoid this, move creating a queue pair and accepting a client from transport_ops->prepare() to smb_direct_handle_connect_request(). Acked-by: Namjae Jeon <[email protected]> Signed-off-by: Hyunchul Lee <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent b589f5d commit 99b7650

File tree

1 file changed

+59
-43
lines changed

1 file changed

+59
-43
lines changed

fs/ksmbd/transport_rdma.c

Lines changed: 59 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
568568
}
569569
t->negotiation_requested = true;
570570
t->full_packet_received = true;
571+
enqueue_reassembly(t, recvmsg, 0);
571572
wake_up_interruptible(&t->wait_status);
572573
break;
573574
case SMB_DIRECT_MSG_DATA_TRANSFER: {
@@ -1594,19 +1595,13 @@ static int smb_direct_accept_client(struct smb_direct_transport *t)
15941595
pr_err("error at rdma_accept: %d\n", ret);
15951596
return ret;
15961597
}
1597-
1598-
wait_event_interruptible(t->wait_status,
1599-
t->status != SMB_DIRECT_CS_NEW);
1600-
if (t->status != SMB_DIRECT_CS_CONNECTED)
1601-
return -ENOTCONN;
16021598
return 0;
16031599
}
16041600

1605-
static int smb_direct_negotiate(struct smb_direct_transport *t)
1601+
static int smb_direct_prepare_negotiation(struct smb_direct_transport *t)
16061602
{
16071603
int ret;
16081604
struct smb_direct_recvmsg *recvmsg;
1609-
struct smb_direct_negotiate_req *req;
16101605

16111606
recvmsg = get_free_recvmsg(t);
16121607
if (!recvmsg)
@@ -1616,44 +1611,20 @@ static int smb_direct_negotiate(struct smb_direct_transport *t)
16161611
ret = smb_direct_post_recv(t, recvmsg);
16171612
if (ret) {
16181613
pr_err("Can't post recv: %d\n", ret);
1619-
goto out;
1614+
goto out_err;
16201615
}
16211616

16221617
t->negotiation_requested = false;
16231618
ret = smb_direct_accept_client(t);
16241619
if (ret) {
16251620
pr_err("Can't accept client\n");
1626-
goto out;
1621+
goto out_err;
16271622
}
16281623

16291624
smb_direct_post_recv_credits(&t->post_recv_credits_work.work);
1630-
1631-
ksmbd_debug(RDMA, "Waiting for SMB_DIRECT negotiate request\n");
1632-
ret = wait_event_interruptible_timeout(t->wait_status,
1633-
t->negotiation_requested ||
1634-
t->status == SMB_DIRECT_CS_DISCONNECTED,
1635-
SMB_DIRECT_NEGOTIATE_TIMEOUT * HZ);
1636-
if (ret <= 0 || t->status == SMB_DIRECT_CS_DISCONNECTED) {
1637-
ret = ret < 0 ? ret : -ETIMEDOUT;
1638-
goto out;
1639-
}
1640-
1641-
ret = smb_direct_check_recvmsg(recvmsg);
1642-
if (ret == -ECONNABORTED)
1643-
goto out;
1644-
1645-
req = (struct smb_direct_negotiate_req *)recvmsg->packet;
1646-
t->max_recv_size = min_t(int, t->max_recv_size,
1647-
le32_to_cpu(req->preferred_send_size));
1648-
t->max_send_size = min_t(int, t->max_send_size,
1649-
le32_to_cpu(req->max_receive_size));
1650-
t->max_fragmented_send_size =
1651-
le32_to_cpu(req->max_fragmented_size);
1652-
1653-
ret = smb_direct_send_negotiate_response(t, ret);
1654-
out:
1655-
if (recvmsg)
1656-
put_recvmsg(t, recvmsg);
1625+
return 0;
1626+
out_err:
1627+
put_recvmsg(t, recvmsg);
16571628
return ret;
16581629
}
16591630

@@ -1890,6 +1861,47 @@ static int smb_direct_create_qpair(struct smb_direct_transport *t,
18901861
static int smb_direct_prepare(struct ksmbd_transport *t)
18911862
{
18921863
struct smb_direct_transport *st = smb_trans_direct_transfort(t);
1864+
struct smb_direct_recvmsg *recvmsg;
1865+
struct smb_direct_negotiate_req *req;
1866+
int ret;
1867+
1868+
ksmbd_debug(RDMA, "Waiting for SMB_DIRECT negotiate request\n");
1869+
ret = wait_event_interruptible_timeout(st->wait_status,
1870+
st->negotiation_requested ||
1871+
st->status == SMB_DIRECT_CS_DISCONNECTED,
1872+
SMB_DIRECT_NEGOTIATE_TIMEOUT * HZ);
1873+
if (ret <= 0 || st->status == SMB_DIRECT_CS_DISCONNECTED)
1874+
return ret < 0 ? ret : -ETIMEDOUT;
1875+
1876+
recvmsg = get_first_reassembly(st);
1877+
if (!recvmsg)
1878+
return -ECONNABORTED;
1879+
1880+
ret = smb_direct_check_recvmsg(recvmsg);
1881+
if (ret == -ECONNABORTED)
1882+
goto out;
1883+
1884+
req = (struct smb_direct_negotiate_req *)recvmsg->packet;
1885+
st->max_recv_size = min_t(int, st->max_recv_size,
1886+
le32_to_cpu(req->preferred_send_size));
1887+
st->max_send_size = min_t(int, st->max_send_size,
1888+
le32_to_cpu(req->max_receive_size));
1889+
st->max_fragmented_send_size =
1890+
le32_to_cpu(req->max_fragmented_size);
1891+
1892+
ret = smb_direct_send_negotiate_response(st, ret);
1893+
out:
1894+
spin_lock_irq(&st->reassembly_queue_lock);
1895+
st->reassembly_queue_length--;
1896+
list_del(&recvmsg->list);
1897+
spin_unlock_irq(&st->reassembly_queue_lock);
1898+
put_recvmsg(st, recvmsg);
1899+
1900+
return ret;
1901+
}
1902+
1903+
static int smb_direct_connect(struct smb_direct_transport *st)
1904+
{
18931905
int ret;
18941906
struct ib_qp_cap qp_cap;
18951907

@@ -1911,13 +1923,11 @@ static int smb_direct_prepare(struct ksmbd_transport *t)
19111923
return ret;
19121924
}
19131925

1914-
ret = smb_direct_negotiate(st);
1926+
ret = smb_direct_prepare_negotiation(st);
19151927
if (ret) {
19161928
pr_err("Can't negotiate: %d\n", ret);
19171929
return ret;
19181930
}
1919-
1920-
st->status = SMB_DIRECT_CS_CONNECTED;
19211931
return 0;
19221932
}
19231933

@@ -1933,6 +1943,7 @@ static bool rdma_frwr_is_supported(struct ib_device_attr *attrs)
19331943
static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id)
19341944
{
19351945
struct smb_direct_transport *t;
1946+
int ret;
19361947

19371948
if (!rdma_frwr_is_supported(&new_cm_id->device->attrs)) {
19381949
ksmbd_debug(RDMA,
@@ -1945,18 +1956,23 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id)
19451956
if (!t)
19461957
return -ENOMEM;
19471958

1959+
ret = smb_direct_connect(t);
1960+
if (ret)
1961+
goto out_err;
1962+
19481963
KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop,
19491964
KSMBD_TRANS(t)->conn, "ksmbd:r%u",
19501965
smb_direct_port);
19511966
if (IS_ERR(KSMBD_TRANS(t)->handler)) {
1952-
int ret = PTR_ERR(KSMBD_TRANS(t)->handler);
1953-
1967+
ret = PTR_ERR(KSMBD_TRANS(t)->handler);
19541968
pr_err("Can't start thread\n");
1955-
free_transport(t);
1956-
return ret;
1969+
goto out_err;
19571970
}
19581971

19591972
return 0;
1973+
out_err:
1974+
free_transport(t);
1975+
return ret;
19601976
}
19611977

19621978
static int smb_direct_listen_handler(struct rdma_cm_id *cm_id,

0 commit comments

Comments
 (0)