Skip to content

Commit

Permalink
s390/qeth: handle skb allocation error gracefully
Browse files Browse the repository at this point in the history
When current code fails to allocate an skb in the RX path, it drops the
whole RX buffer. Considering the large number of packets that a single
RX buffer might contain, this is quite drastic.

Skip over the packet instead, and try to extract the next packet from
the RX buffer.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Julian Wiedmann authored and David S. Miller committed Nov 15, 2019
1 parent 7d4faee commit 17caeaa
Showing 1 changed file with 10 additions and 15 deletions.
25 changes: 10 additions & 15 deletions drivers/s390/net/qeth_core_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5065,12 +5065,12 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
struct qdio_buffer_element *element = *__element;
struct qdio_buffer *buffer = qethbuffer->buffer;
int offset = *__offset;
bool use_rx_sg = false;
unsigned int headroom;
struct sk_buff *skb;
int skb_len = 0;
void *data_ptr;
int data_len;
int headroom = 0;
int use_rx_sg = 0;

next_packet:
/* qeth_hdr must not cross element boundaries */
Expand All @@ -5086,6 +5086,7 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
switch ((*hdr)->hdr.l2.id) {
case QETH_HEADER_TYPE_LAYER2:
skb_len = (*hdr)->hdr.l2.pkt_length;
headroom = 0;
break;
case QETH_HEADER_TYPE_LAYER3:
skb_len = (*hdr)->hdr.l3.length;
Expand Down Expand Up @@ -5120,11 +5121,10 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
if (!skb_len)
return NULL;

if (((skb_len >= card->options.rx_sg_cb) &&
!IS_OSN(card) &&
(!atomic_read(&card->force_alloc_skb))) ||
(card->options.cq == QETH_CQ_ENABLED))
use_rx_sg = 1;
use_rx_sg = (card->options.cq == QETH_CQ_ENABLED) ||
((skb_len >= card->options.rx_sg_cb) &&
!atomic_read(&card->force_alloc_skb) &&
!IS_OSN(card));

if (use_rx_sg && qethbuffer->rx_skb) {
/* QETH_CQ_ENABLED only: */
Expand All @@ -5135,9 +5135,10 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,

skb = napi_alloc_skb(&card->napi, linear + headroom);
}

if (!skb)
goto no_mem;
if (headroom)
QETH_CARD_STAT_INC(card, rx_dropped_nomem);
else if (headroom)
skb_reserve(skb, headroom);

walk_packet:
Expand Down Expand Up @@ -5184,12 +5185,6 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card,
skb_shinfo(skb)->nr_frags);
}
return skb;
no_mem:
if (net_ratelimit()) {
QETH_CARD_TEXT(card, 2, "noskbmem");
}
QETH_CARD_STAT_INC(card, rx_dropped_nomem);
return NULL;
}
EXPORT_SYMBOL_GPL(qeth_core_get_next_skb);

Expand Down

0 comments on commit 17caeaa

Please sign in to comment.