Skip to content

Commit 7cf20bc

Browse files
longlimsftSteve French
authored andcommitted
CIFS: SMBD: Support page offset in memory registration
Change code to pass the correct page offset during memory registration for RDMA read/write. Signed-off-by: Long Li <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 6509f50 commit 7cf20bc

File tree

3 files changed

+58
-38
lines changed

3 files changed

+58
-38
lines changed

fs/cifs/smb2pdu.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2720,8 +2720,8 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
27202720

27212721
rdata->mr = smbd_register_mr(
27222722
server->smbd_conn, rdata->pages,
2723-
rdata->nr_pages, rdata->tailsz,
2724-
true, need_invalidate);
2723+
rdata->nr_pages, rdata->page_offset,
2724+
rdata->tailsz, true, need_invalidate);
27252725
if (!rdata->mr)
27262726
return -ENOBUFS;
27272727

@@ -3107,16 +3107,22 @@ smb2_async_writev(struct cifs_writedata *wdata,
31073107

31083108
wdata->mr = smbd_register_mr(
31093109
server->smbd_conn, wdata->pages,
3110-
wdata->nr_pages, wdata->tailsz,
3111-
false, need_invalidate);
3110+
wdata->nr_pages, wdata->page_offset,
3111+
wdata->tailsz, false, need_invalidate);
31123112
if (!wdata->mr) {
31133113
rc = -ENOBUFS;
31143114
goto async_writev_out;
31153115
}
31163116
req->Length = 0;
31173117
req->DataOffset = 0;
3118-
req->RemainingBytes =
3119-
cpu_to_le32((wdata->nr_pages-1)*PAGE_SIZE + wdata->tailsz);
3118+
if (wdata->nr_pages > 1)
3119+
req->RemainingBytes =
3120+
cpu_to_le32(
3121+
(wdata->nr_pages - 1) * wdata->pagesz -
3122+
wdata->page_offset + wdata->tailsz
3123+
);
3124+
else
3125+
req->RemainingBytes = cpu_to_le32(wdata->tailsz);
31203126
req->Channel = SMB2_CHANNEL_RDMA_V1_INVALIDATE;
31213127
if (need_invalidate)
31223128
req->Channel = SMB2_CHANNEL_RDMA_V1;

fs/cifs/smbdirect.c

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2299,37 +2299,37 @@ static void smbd_mr_recovery_work(struct work_struct *work)
22992299
if (smbdirect_mr->state == MR_INVALIDATED ||
23002300
smbdirect_mr->state == MR_ERROR) {
23012301

2302-
if (smbdirect_mr->state == MR_INVALIDATED) {
2302+
/* recover this MR entry */
2303+
rc = ib_dereg_mr(smbdirect_mr->mr);
2304+
if (rc) {
2305+
log_rdma_mr(ERR,
2306+
"ib_dereg_mr failed rc=%x\n",
2307+
rc);
2308+
smbd_disconnect_rdma_connection(info);
2309+
continue;
2310+
}
2311+
2312+
smbdirect_mr->mr = ib_alloc_mr(
2313+
info->pd, info->mr_type,
2314+
info->max_frmr_depth);
2315+
if (IS_ERR(smbdirect_mr->mr)) {
2316+
log_rdma_mr(ERR,
2317+
"ib_alloc_mr failed mr_type=%x "
2318+
"max_frmr_depth=%x\n",
2319+
info->mr_type,
2320+
info->max_frmr_depth);
2321+
smbd_disconnect_rdma_connection(info);
2322+
continue;
2323+
}
2324+
2325+
if (smbdirect_mr->state == MR_INVALIDATED)
23032326
ib_dma_unmap_sg(
23042327
info->id->device, smbdirect_mr->sgl,
23052328
smbdirect_mr->sgl_count,
23062329
smbdirect_mr->dir);
2307-
smbdirect_mr->state = MR_READY;
2308-
} else if (smbdirect_mr->state == MR_ERROR) {
2309-
2310-
/* recover this MR entry */
2311-
rc = ib_dereg_mr(smbdirect_mr->mr);
2312-
if (rc) {
2313-
log_rdma_mr(ERR,
2314-
"ib_dereg_mr failed rc=%x\n",
2315-
rc);
2316-
smbd_disconnect_rdma_connection(info);
2317-
}
23182330

2319-
smbdirect_mr->mr = ib_alloc_mr(
2320-
info->pd, info->mr_type,
2321-
info->max_frmr_depth);
2322-
if (IS_ERR(smbdirect_mr->mr)) {
2323-
log_rdma_mr(ERR,
2324-
"ib_alloc_mr failed mr_type=%x "
2325-
"max_frmr_depth=%x\n",
2326-
info->mr_type,
2327-
info->max_frmr_depth);
2328-
smbd_disconnect_rdma_connection(info);
2329-
}
2331+
smbdirect_mr->state = MR_READY;
23302332

2331-
smbdirect_mr->state = MR_READY;
2332-
}
23332333
/* smbdirect_mr->state is updated by this function
23342334
* and is read and updated by I/O issuing CPUs trying
23352335
* to get a MR, the call to atomic_inc_return
@@ -2475,7 +2475,7 @@ static struct smbd_mr *get_mr(struct smbd_connection *info)
24752475
*/
24762476
struct smbd_mr *smbd_register_mr(
24772477
struct smbd_connection *info, struct page *pages[], int num_pages,
2478-
int tailsz, bool writing, bool need_invalidate)
2478+
int offset, int tailsz, bool writing, bool need_invalidate)
24792479
{
24802480
struct smbd_mr *smbdirect_mr;
24812481
int rc, i;
@@ -2498,26 +2498,40 @@ struct smbd_mr *smbd_register_mr(
24982498
smbdirect_mr->sgl_count = num_pages;
24992499
sg_init_table(smbdirect_mr->sgl, num_pages);
25002500

2501-
for (i = 0; i < num_pages - 1; i++)
2502-
sg_set_page(&smbdirect_mr->sgl[i], pages[i], PAGE_SIZE, 0);
2501+
log_rdma_mr(INFO, "num_pages=0x%x offset=0x%x tailsz=0x%x\n",
2502+
num_pages, offset, tailsz);
25032503

2504+
if (num_pages == 1) {
2505+
sg_set_page(&smbdirect_mr->sgl[0], pages[0], tailsz, offset);
2506+
goto skip_multiple_pages;
2507+
}
2508+
2509+
/* We have at least two pages to register */
2510+
sg_set_page(
2511+
&smbdirect_mr->sgl[0], pages[0], PAGE_SIZE - offset, offset);
2512+
i = 1;
2513+
while (i < num_pages - 1) {
2514+
sg_set_page(&smbdirect_mr->sgl[i], pages[i], PAGE_SIZE, 0);
2515+
i++;
2516+
}
25042517
sg_set_page(&smbdirect_mr->sgl[i], pages[i],
25052518
tailsz ? tailsz : PAGE_SIZE, 0);
25062519

2520+
skip_multiple_pages:
25072521
dir = writing ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
25082522
smbdirect_mr->dir = dir;
25092523
rc = ib_dma_map_sg(info->id->device, smbdirect_mr->sgl, num_pages, dir);
25102524
if (!rc) {
2511-
log_rdma_mr(INFO, "ib_dma_map_sg num_pages=%x dir=%x rc=%x\n",
2525+
log_rdma_mr(ERR, "ib_dma_map_sg num_pages=%x dir=%x rc=%x\n",
25122526
num_pages, dir, rc);
25132527
goto dma_map_error;
25142528
}
25152529

25162530
rc = ib_map_mr_sg(smbdirect_mr->mr, smbdirect_mr->sgl, num_pages,
25172531
NULL, PAGE_SIZE);
25182532
if (rc != num_pages) {
2519-
log_rdma_mr(INFO,
2520-
"ib_map_mr_sg failed rc = %x num_pages = %x\n",
2533+
log_rdma_mr(ERR,
2534+
"ib_map_mr_sg failed rc = %d num_pages = %x\n",
25212535
rc, num_pages);
25222536
goto map_mr_error;
25232537
}

fs/cifs/smbdirect.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ struct smbd_mr {
321321
/* Interfaces to register and deregister MR for RDMA read/write */
322322
struct smbd_mr *smbd_register_mr(
323323
struct smbd_connection *info, struct page *pages[], int num_pages,
324-
int tailsz, bool writing, bool need_invalidate);
324+
int offset, int tailsz, bool writing, bool need_invalidate);
325325
int smbd_deregister_mr(struct smbd_mr *mr);
326326

327327
#else

0 commit comments

Comments
 (0)