Skip to content

Commit 60b8666

Browse files
shemmingerdavem330
authored andcommitted
netvsc: optimize calculation of number of slots
Speed up transmit check for fragmented packets by using existing macros to compute number of pages, and eliminate loop since skb fragments each take a page. Number of slots is also unsigned. Signed-off-by: Stephen Hemminger <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent e073782 commit 60b8666

File tree

1 file changed

+10
-33
lines changed

1 file changed

+10
-33
lines changed

drivers/net/hyperv/netvsc_drv.c

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -345,34 +345,14 @@ static u32 init_page_array(void *hdr, u32 len, struct sk_buff *skb,
345345
return slots_used;
346346
}
347347

348-
static int count_skb_frag_slots(struct sk_buff *skb)
349-
{
350-
int i, frags = skb_shinfo(skb)->nr_frags;
351-
int pages = 0;
352-
353-
for (i = 0; i < frags; i++) {
354-
skb_frag_t *frag = skb_shinfo(skb)->frags + i;
355-
unsigned long size = skb_frag_size(frag);
356-
unsigned long offset = frag->page_offset;
357-
358-
/* Skip unused frames from start of page */
359-
offset &= ~PAGE_MASK;
360-
pages += PFN_UP(offset + size);
361-
}
362-
return pages;
363-
}
364-
365-
static int netvsc_get_slots(struct sk_buff *skb)
348+
/* Estimate number of page buffers neede to transmit
349+
* Need at most 2 for RNDIS header plus skb body and fragments.
350+
*/
351+
static unsigned int netvsc_get_slots(const struct sk_buff *skb)
366352
{
367-
char *data = skb->data;
368-
unsigned int offset = offset_in_page(data);
369-
unsigned int len = skb_headlen(skb);
370-
int slots;
371-
int frag_slots;
372-
373-
slots = DIV_ROUND_UP(offset + len, PAGE_SIZE);
374-
frag_slots = count_skb_frag_slots(skb);
375-
return slots + frag_slots;
353+
return PFN_UP(offset_in_page(skb->data) + skb_headlen(skb))
354+
+ skb_shinfo(skb)->nr_frags
355+
+ 2;
376356
}
377357

378358
static u32 net_checksum_info(struct sk_buff *skb)
@@ -410,21 +390,18 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
410390
struct hv_page_buffer page_buf[MAX_PAGE_BUFFER_COUNT];
411391
struct hv_page_buffer *pb = page_buf;
412392

413-
/* We will atmost need two pages to describe the rndis
414-
* header. We can only transmit MAX_PAGE_BUFFER_COUNT number
393+
/* We can only transmit MAX_PAGE_BUFFER_COUNT number
415394
* of pages in a single packet. If skb is scattered around
416395
* more pages we try linearizing it.
417396
*/
418-
419-
num_data_pgs = netvsc_get_slots(skb) + 2;
420-
397+
num_data_pgs = netvsc_get_slots(skb);
421398
if (unlikely(num_data_pgs > MAX_PAGE_BUFFER_COUNT)) {
422399
++net_device_ctx->eth_stats.tx_scattered;
423400

424401
if (skb_linearize(skb))
425402
goto no_memory;
426403

427-
num_data_pgs = netvsc_get_slots(skb) + 2;
404+
num_data_pgs = netvsc_get_slots(skb);
428405
if (num_data_pgs > MAX_PAGE_BUFFER_COUNT) {
429406
++net_device_ctx->eth_stats.tx_too_big;
430407
goto drop;

0 commit comments

Comments
 (0)