diff options
| -rw-r--r-- | drivers/net/xen-netback/netback.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 72314c7998fc..573f3e81e5d2 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
| @@ -493,9 +493,28 @@ static void xenvif_rx_action(struct xenvif *vif) | |||
| 493 | PAGE_SIZE); | 493 | PAGE_SIZE); |
| 494 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | 494 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
| 495 | unsigned int size; | 495 | unsigned int size; |
| 496 | unsigned int offset; | ||
| 497 | |||
| 496 | size = skb_frag_size(&skb_shinfo(skb)->frags[i]); | 498 | size = skb_frag_size(&skb_shinfo(skb)->frags[i]); |
| 497 | max_slots_needed += DIV_ROUND_UP(size, PAGE_SIZE); | 499 | offset = skb_shinfo(skb)->frags[i].page_offset; |
| 500 | |||
| 501 | /* For a worse-case estimate we need to factor in | ||
| 502 | * the fragment page offset as this will affect the | ||
| 503 | * number of times xenvif_gop_frag_copy() will | ||
| 504 | * call start_new_rx_buffer(). | ||
| 505 | */ | ||
| 506 | max_slots_needed += DIV_ROUND_UP(offset + size, | ||
| 507 | PAGE_SIZE); | ||
| 498 | } | 508 | } |
| 509 | |||
| 510 | /* To avoid the estimate becoming too pessimal for some | ||
| 511 | * frontends that limit posted rx requests, cap the estimate | ||
| 512 | * at MAX_SKB_FRAGS. | ||
| 513 | */ | ||
| 514 | if (max_slots_needed > MAX_SKB_FRAGS) | ||
| 515 | max_slots_needed = MAX_SKB_FRAGS; | ||
| 516 | |||
| 517 | /* We may need one more slot for GSO metadata */ | ||
| 499 | if (skb_is_gso(skb) && | 518 | if (skb_is_gso(skb) && |
| 500 | (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 || | 519 | (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4 || |
| 501 | skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)) | 520 | skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)) |
