Skip to content

Commit 12472af

Browse files
julianwiedmanndavem330
authored andcommitted
s390/qeth: fix overestimated count of buffer elements
qeth_get_elements_for_range() doesn't know how to handle a 0-length range (ie. start == end), and returns 1 when it should return 0. Such ranges occur on TSO skbs, where the L2/L3/L4 headers (and thus all of the skb's linear data) are skipped when mapping the skb into regular buffer elements. This overestimation may cause several performance-related issues: 1. sub-optimal IO buffer selection, where the next buffer gets selected even though the skb would actually still fit into the current buffer. 2. forced linearization, if the element count for a non-linear skb exceeds QETH_MAX_BUFFER_ELEMENTS. Rather than modifying qeth_get_elements_for_range() and adding overhead to every caller, fix up those callers that are in risk of passing a 0-length range. Fixes: 2863c61 ("qeth: refactor calculation of SBALE count") Signed-off-by: Julian Wiedmann <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 590399d commit 12472af

File tree

2 files changed

+12
-9
lines changed

2 files changed

+12
-9
lines changed

drivers/s390/net/qeth_core_main.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3898,10 +3898,12 @@ EXPORT_SYMBOL_GPL(qeth_get_elements_for_frags);
38983898
int qeth_get_elements_no(struct qeth_card *card,
38993899
struct sk_buff *skb, int extra_elems, int data_offset)
39003900
{
3901-
int elements = qeth_get_elements_for_range(
3902-
(addr_t)skb->data + data_offset,
3903-
(addr_t)skb->data + skb_headlen(skb)) +
3904-
qeth_get_elements_for_frags(skb);
3901+
addr_t end = (addr_t)skb->data + skb_headlen(skb);
3902+
int elements = qeth_get_elements_for_frags(skb);
3903+
addr_t start = (addr_t)skb->data + data_offset;
3904+
3905+
if (start != end)
3906+
elements += qeth_get_elements_for_range(start, end);
39053907

39063908
if ((elements + extra_elems) > QETH_MAX_BUFFER_ELEMENTS(card)) {
39073909
QETH_DBF_MESSAGE(2, "Invalid size of IP packet "

drivers/s390/net/qeth_l3_main.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2450,11 +2450,12 @@ static void qeth_tso_fill_header(struct qeth_card *card,
24502450
static int qeth_l3_get_elements_no_tso(struct qeth_card *card,
24512451
struct sk_buff *skb, int extra_elems)
24522452
{
2453-
addr_t tcpdptr = (addr_t)tcp_hdr(skb) + tcp_hdrlen(skb);
2454-
int elements = qeth_get_elements_for_range(
2455-
tcpdptr,
2456-
(addr_t)skb->data + skb_headlen(skb)) +
2457-
qeth_get_elements_for_frags(skb);
2453+
addr_t start = (addr_t)tcp_hdr(skb) + tcp_hdrlen(skb);
2454+
addr_t end = (addr_t)skb->data + skb_headlen(skb);
2455+
int elements = qeth_get_elements_for_frags(skb);
2456+
2457+
if (start != end)
2458+
elements += qeth_get_elements_for_range(start, end);
24582459

24592460
if ((elements + extra_elems) > QETH_MAX_BUFFER_ELEMENTS(card)) {
24602461
QETH_DBF_MESSAGE(2,

0 commit comments

Comments
 (0)