smb: client: let smbd_post_send_iter() call ib_dma_map_single() for the header first

This will simplify further changes, the important part is that
request->num_sge >= 1 is only set if request->sge[0].* is valid.

Note that ib_dma_sync_single_for_device() is called in
smbd_post_send() for each sge, so the device will still
see the packet header even if it's modified after calling
ib_dma_map_single().

Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Acked-by: 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>
This commit is contained in:
Stefan Metzmacher
2025-09-15 00:55:31 +02:00
committed by Steve French
parent c4709e61ef
commit 2dad0b15bb

View File

@@ -1158,10 +1158,30 @@ static int smbd_post_send_iter(struct smbdirect_socket *sc,
request->socket = sc;
memset(request->sge, 0, sizeof(request->sge));
/* Map the packet to DMA */
header_length = sizeof(struct smbdirect_data_transfer);
/* If this is a packet without payload, don't send padding */
if (!iter)
header_length = offsetof(struct smbdirect_data_transfer, padding);
packet = smbdirect_send_io_payload(request);
request->sge[0].addr = ib_dma_map_single(sc->ib.dev,
(void *)packet,
header_length,
DMA_TO_DEVICE);
if (ib_dma_mapping_error(sc->ib.dev, request->sge[0].addr)) {
rc = -EIO;
goto err_dma;
}
request->sge[0].length = header_length;
request->sge[0].lkey = sc->ib.pd->local_dma_lkey;
request->num_sge = 1;
/* Fill in the data payload to find out how much data we can add */
if (iter) {
struct smb_extract_to_rdma extract = {
.nr_sge = 1,
.nr_sge = request->num_sge,
.max_sge = SMBDIRECT_SEND_IO_MAX_SGE,
.sge = request->sge,
.device = sc->ib.dev,
@@ -1180,11 +1200,9 @@ static int smbd_post_send_iter(struct smbdirect_socket *sc,
*_remaining_data_length -= data_length;
} else {
data_length = 0;
request->num_sge = 1;
}
/* Fill in the packet header */
packet = smbdirect_send_io_payload(request);
packet->credits_requested = cpu_to_le16(sp->send_credit_target);
new_credits = manage_credits_prior_sending(sc);
@@ -1211,25 +1229,6 @@ static int smbd_post_send_iter(struct smbdirect_socket *sc,
le32_to_cpu(packet->data_length),
le32_to_cpu(packet->remaining_data_length));
/* Map the packet to DMA */
header_length = sizeof(struct smbdirect_data_transfer);
/* If this is a packet without payload, don't send padding */
if (!data_length)
header_length = offsetof(struct smbdirect_data_transfer, padding);
request->sge[0].addr = ib_dma_map_single(sc->ib.dev,
(void *)packet,
header_length,
DMA_TO_DEVICE);
if (ib_dma_mapping_error(sc->ib.dev, request->sge[0].addr)) {
rc = -EIO;
request->sge[0].addr = 0;
goto err_dma;
}
request->sge[0].length = header_length;
request->sge[0].lkey = sc->ib.pd->local_dma_lkey;
rc = smbd_post_send(sc, request);
if (!rc)
return 0;