Skip to content

Commit 2153812

Browse files
metze-sambasmfrench
authored andcommitted
smb: client: make use of smbdirect_socket.send_io.bcredits
It turns out that our code will corrupt the stream of reassabled data transfer messages when we trigger an immendiate (empty) send. In order to fix this we'll have a single 'batch' credit per connection. And code getting that credit is free to use as much messages until remaining_length reaches 0, then the batch credit it given back and the next logical send can happen. Cc: <stable@vger.kernel.org> # 6.18.x Cc: Steve French <smfrench@gmail.com> Cc: Tom Talpey <tom@talpey.com> Cc: Long Li <longli@microsoft.com> Cc: Namjae Jeon <linkinjeon@kernel.org> Cc: linux-cifs@vger.kernel.org Cc: samba-technical@lists.samba.org Signed-off-by: Stefan Metzmacher <metze@samba.org> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 2c1ac39 commit 2153812

1 file changed

Lines changed: 55 additions & 3 deletions

File tree

fs/smb/client/smbdirect.c

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,7 @@ static bool process_negotiation_response(
657657
sp->max_frmr_depth * PAGE_SIZE);
658658
sp->max_frmr_depth = sp->max_read_write_size / PAGE_SIZE;
659659

660+
atomic_set(&sc->send_io.bcredits.count, 1);
660661
sc->recv_io.expected = SMBDIRECT_EXPECT_DATA_TRANSFER;
661662
return true;
662663
}
@@ -1214,6 +1215,7 @@ static void smbd_send_batch_init(struct smbdirect_send_batch *batch,
12141215
batch->wr_cnt = 0;
12151216
batch->need_invalidate_rkey = need_invalidate_rkey;
12161217
batch->remote_key = remote_key;
1218+
batch->credit = 0;
12171219
}
12181220

12191221
static int smbd_send_batch_flush(struct smbdirect_socket *sc,
@@ -1224,7 +1226,7 @@ static int smbd_send_batch_flush(struct smbdirect_socket *sc,
12241226
int ret = 0;
12251227

12261228
if (list_empty(&batch->msg_list))
1227-
return 0;
1229+
goto release_credit;
12281230

12291231
first = list_first_entry(&batch->msg_list,
12301232
struct smbdirect_send_io,
@@ -1266,6 +1268,13 @@ static int smbd_send_batch_flush(struct smbdirect_socket *sc,
12661268
smbd_free_send_io(last);
12671269
}
12681270

1271+
release_credit:
1272+
if (is_last && !ret && batch->credit) {
1273+
atomic_add(batch->credit, &sc->send_io.bcredits.count);
1274+
batch->credit = 0;
1275+
wake_up(&sc->send_io.bcredits.wait_queue);
1276+
}
1277+
12691278
return ret;
12701279
}
12711280

@@ -1291,6 +1300,25 @@ static int wait_for_credits(struct smbdirect_socket *sc,
12911300
} while (true);
12921301
}
12931302

1303+
static int wait_for_send_bcredit(struct smbdirect_socket *sc,
1304+
struct smbdirect_send_batch *batch)
1305+
{
1306+
int ret;
1307+
1308+
if (batch->credit)
1309+
return 0;
1310+
1311+
ret = wait_for_credits(sc,
1312+
&sc->send_io.bcredits.wait_queue,
1313+
&sc->send_io.bcredits.count,
1314+
1);
1315+
if (ret)
1316+
return ret;
1317+
1318+
batch->credit = 1;
1319+
return 0;
1320+
}
1321+
12941322
static int wait_for_send_lcredit(struct smbdirect_socket *sc,
12951323
struct smbdirect_send_batch *batch)
12961324
{
@@ -1338,6 +1366,19 @@ static int smbd_post_send_iter(struct smbdirect_socket *sc,
13381366
struct smbdirect_send_io *request;
13391367
struct smbdirect_data_transfer *packet;
13401368
int new_credits = 0;
1369+
struct smbdirect_send_batch _batch;
1370+
1371+
if (!batch) {
1372+
smbd_send_batch_init(&_batch, false, 0);
1373+
batch = &_batch;
1374+
}
1375+
1376+
rc = wait_for_send_bcredit(sc, batch);
1377+
if (rc) {
1378+
log_outgoing(ERR, "disconnected not sending on wait_bcredit\n");
1379+
rc = -EAGAIN;
1380+
goto err_wait_bcredit;
1381+
}
13411382

13421383
rc = wait_for_send_lcredit(sc, batch);
13431384
if (rc) {
@@ -1432,8 +1473,14 @@ static int smbd_post_send_iter(struct smbdirect_socket *sc,
14321473
le32_to_cpu(packet->remaining_data_length));
14331474

14341475
rc = smbd_post_send(sc, batch, request);
1435-
if (!rc)
1436-
return 0;
1476+
if (!rc) {
1477+
if (batch != &_batch)
1478+
return 0;
1479+
1480+
rc = smbd_send_batch_flush(sc, batch, true);
1481+
if (!rc)
1482+
return 0;
1483+
}
14371484

14381485
err_dma:
14391486
smbd_free_send_io(request);
@@ -1447,6 +1494,11 @@ static int smbd_post_send_iter(struct smbdirect_socket *sc,
14471494
wake_up(&sc->send_io.lcredits.wait_queue);
14481495

14491496
err_wait_lcredit:
1497+
atomic_add(batch->credit, &sc->send_io.bcredits.count);
1498+
batch->credit = 0;
1499+
wake_up(&sc->send_io.bcredits.wait_queue);
1500+
1501+
err_wait_bcredit:
14501502
return rc;
14511503
}
14521504

0 commit comments

Comments
 (0)