diff options
author | Jason Wang <jasowang@redhat.com> | 2012-05-01 23:41:30 -0400 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2012-05-02 11:22:17 -0400 |
commit | 3afc9621f15701c557e60f61eba9242bac2771dd (patch) | |
tree | b4fc1cda638c3bc4fb3c4fca80cd27bd03d9ea3b /drivers/net/macvtap.c | |
parent | 64d098886e0ec01f88349fe757161c2e2e89086b (diff) |
macvtap: zerocopy: fix offset calculation when building skb
This patch fixes the offset calculation when building skb:
- offset1 were used as skb data offset not vector offset
- reset offset to zero only when we advance to next vector
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/net/macvtap.c')
-rw-r--r-- | drivers/net/macvtap.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 0427c6561c84..bd4a70d8605f 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
@@ -505,10 +505,11 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, | |||
505 | if (copy > size) { | 505 | if (copy > size) { |
506 | ++from; | 506 | ++from; |
507 | --count; | 507 | --count; |
508 | } | 508 | offset = 0; |
509 | } else | ||
510 | offset += size; | ||
509 | copy -= size; | 511 | copy -= size; |
510 | offset1 += size; | 512 | offset1 += size; |
511 | offset = 0; | ||
512 | } | 513 | } |
513 | 514 | ||
514 | if (len == offset1) | 515 | if (len == offset1) |
@@ -519,13 +520,13 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, | |||
519 | int num_pages; | 520 | int num_pages; |
520 | unsigned long base; | 521 | unsigned long base; |
521 | 522 | ||
522 | len = from->iov_len - offset1; | 523 | len = from->iov_len - offset; |
523 | if (!len) { | 524 | if (!len) { |
524 | offset1 = 0; | 525 | offset = 0; |
525 | ++from; | 526 | ++from; |
526 | continue; | 527 | continue; |
527 | } | 528 | } |
528 | base = (unsigned long)from->iov_base + offset1; | 529 | base = (unsigned long)from->iov_base + offset; |
529 | size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT; | 530 | size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT; |
530 | num_pages = get_user_pages_fast(base, size, 0, &page[i]); | 531 | num_pages = get_user_pages_fast(base, size, 0, &page[i]); |
531 | if ((num_pages != size) || | 532 | if ((num_pages != size) || |
@@ -546,7 +547,7 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, | |||
546 | len -= size; | 547 | len -= size; |
547 | i++; | 548 | i++; |
548 | } | 549 | } |
549 | offset1 = 0; | 550 | offset = 0; |
550 | ++from; | 551 | ++from; |
551 | } | 552 | } |
552 | return 0; | 553 | return 0; |