Skip to content

Commit

Permalink
cxgbit: fix sg_nents calculation
Browse files Browse the repository at this point in the history
The current logic of calculating sg_nents can fail
if data_offset % PAGE_SIZE is not zero.

For example -
PAGE_SIZE = 4096
data_len = 3072
data_offset = 3072

As per current logic
sg_nents = max(1UL, DIV_ROUND_UP(data_len, PAGE_SIZE));
sg_nents = max(1UL, DIV_ROUND_UP(3072, 4096));
sg_nents = 1

But as data_offset % PAGE_SIZE = 3072 we should skip 3072 bytes
skip = 3K
sg_nents = max(1UL, DIV_ROUND_UP(3K(skip) + 3K(data_len), 4K(PAGE_SIZE));
sg_nents = 2;

This patch fixes this issue by adding skip to data_len.

Signed-off-by: Varun Prakash <varun@chelsio.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
  • Loading branch information
Varun Prakash authored and Nicholas Bellinger committed Jul 30, 2017
1 parent 310d40a commit d96adb9
Showing 1 changed file with 7 additions and 5 deletions.
12 changes: 7 additions & 5 deletions drivers/target/iscsi/cxgbit/cxgbit_target.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ cxgbit_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login,

static void
cxgbit_skb_copy_to_sg(struct sk_buff *skb, struct scatterlist *sg,
unsigned int nents)
unsigned int nents, u32 skip)
{
struct skb_seq_state st;
const u8 *buf;
Expand All @@ -846,7 +846,7 @@ cxgbit_skb_copy_to_sg(struct sk_buff *skb, struct scatterlist *sg,
}

consumed += sg_pcopy_from_buffer(sg, nents, (void *)buf,
buf_len, consumed);
buf_len, skip + consumed);
}
}

Expand Down Expand Up @@ -912,7 +912,7 @@ cxgbit_handle_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
struct scatterlist *sg = &cmd->se_cmd.t_data_sg[0];
u32 sg_nents = max(1UL, DIV_ROUND_UP(pdu_cb->dlen, PAGE_SIZE));

cxgbit_skb_copy_to_sg(csk->skb, sg, sg_nents);
cxgbit_skb_copy_to_sg(csk->skb, sg, sg_nents, 0);
}

cmd->write_data_done += pdu_cb->dlen;
Expand Down Expand Up @@ -1069,11 +1069,13 @@ static int cxgbit_handle_iscsi_dataout(struct cxgbit_sock *csk)
cmd->se_cmd.data_length);

if (!(pdu_cb->flags & PDUCBF_RX_DATA_DDPD)) {
u32 skip = data_offset % PAGE_SIZE;

sg_off = data_offset / PAGE_SIZE;
sg_start = &cmd->se_cmd.t_data_sg[sg_off];
sg_nents = max(1UL, DIV_ROUND_UP(data_len, PAGE_SIZE));
sg_nents = max(1UL, DIV_ROUND_UP(skip + data_len, PAGE_SIZE));

cxgbit_skb_copy_to_sg(csk->skb, sg_start, sg_nents);
cxgbit_skb_copy_to_sg(csk->skb, sg_start, sg_nents, skip);
}

check_payload:
Expand Down

0 comments on commit d96adb9

Please sign in to comment.