@@ -250,24 +250,6 @@ static void skb_xmit_done(struct virtqueue *vq)
250
250
netif_wake_subqueue (vi -> dev , vq2txq (vq ));
251
251
}
252
252
253
- static unsigned int mergeable_ctx_to_buf_truesize (unsigned long mrg_ctx )
254
- {
255
- unsigned int truesize = mrg_ctx & (MERGEABLE_BUFFER_ALIGN - 1 );
256
- return (truesize + 1 ) * MERGEABLE_BUFFER_ALIGN ;
257
- }
258
-
259
- static void * mergeable_ctx_to_buf_address (unsigned long mrg_ctx )
260
- {
261
- return (void * )(mrg_ctx & - MERGEABLE_BUFFER_ALIGN );
262
-
263
- }
264
-
265
- static unsigned long mergeable_buf_to_ctx (void * buf , unsigned int truesize )
266
- {
267
- unsigned int size = truesize / MERGEABLE_BUFFER_ALIGN ;
268
- return (unsigned long )buf | (size - 1 );
269
- }
270
-
271
253
/* Called from bottom half context */
272
254
static struct sk_buff * page_to_skb (struct virtnet_info * vi ,
273
255
struct receive_queue * rq ,
@@ -511,15 +493,13 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
511
493
512
494
while (-- * num_buf ) {
513
495
unsigned int buflen ;
514
- unsigned long ctx ;
515
496
void * buf ;
516
497
int off ;
517
498
518
- ctx = ( unsigned long ) virtqueue_get_buf (rq -> vq , & buflen );
519
- if (unlikely (!ctx ))
499
+ buf = virtqueue_get_buf (rq -> vq , & buflen );
500
+ if (unlikely (!buf ))
520
501
goto err_buf ;
521
502
522
- buf = mergeable_ctx_to_buf_address (ctx );
523
503
p = virt_to_head_page (buf );
524
504
off = buf - page_address (p );
525
505
@@ -548,10 +528,10 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
548
528
static struct sk_buff * receive_mergeable (struct net_device * dev ,
549
529
struct virtnet_info * vi ,
550
530
struct receive_queue * rq ,
551
- unsigned long ctx ,
531
+ void * buf ,
532
+ void * ctx ,
552
533
unsigned int len )
553
534
{
554
- void * buf = mergeable_ctx_to_buf_address (ctx );
555
535
struct virtio_net_hdr_mrg_rxbuf * hdr = buf ;
556
536
u16 num_buf = virtio16_to_cpu (vi -> vdev , hdr -> num_buffers );
557
537
struct page * page = virt_to_head_page (buf );
@@ -639,7 +619,13 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
639
619
}
640
620
rcu_read_unlock ();
641
621
642
- truesize = max (len , mergeable_ctx_to_buf_truesize (ctx ));
622
+ if (unlikely (len > (unsigned long )ctx )) {
623
+ pr_debug ("%s: rx error: len %u exceeds truesize 0x%lu\n" ,
624
+ dev -> name , len , (unsigned long )ctx );
625
+ dev -> stats .rx_length_errors ++ ;
626
+ goto err_skb ;
627
+ }
628
+ truesize = (unsigned long )ctx ;
643
629
head_skb = page_to_skb (vi , rq , page , offset , len , truesize );
644
630
curr_skb = head_skb ;
645
631
@@ -648,7 +634,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
648
634
while (-- num_buf ) {
649
635
int num_skb_frags ;
650
636
651
- ctx = ( unsigned long ) virtqueue_get_buf ( rq -> vq , & len );
637
+ buf = virtqueue_get_buf_ctx ( rq -> vq , & len , & ctx );
652
638
if (unlikely (!ctx )) {
653
639
pr_debug ("%s: rx error: %d buffers out of %d missing\n" ,
654
640
dev -> name , num_buf ,
@@ -658,8 +644,14 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
658
644
goto err_buf ;
659
645
}
660
646
661
- buf = mergeable_ctx_to_buf_address (ctx );
662
647
page = virt_to_head_page (buf );
648
+ if (unlikely (len > (unsigned long )ctx )) {
649
+ pr_debug ("%s: rx error: len %u exceeds truesize 0x%lu\n" ,
650
+ dev -> name , len , (unsigned long )ctx );
651
+ dev -> stats .rx_length_errors ++ ;
652
+ goto err_skb ;
653
+ }
654
+ truesize = (unsigned long )ctx ;
663
655
664
656
num_skb_frags = skb_shinfo (curr_skb )-> nr_frags ;
665
657
if (unlikely (num_skb_frags == MAX_SKB_FRAGS )) {
@@ -675,7 +667,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
675
667
head_skb -> truesize += nskb -> truesize ;
676
668
num_skb_frags = 0 ;
677
669
}
678
- truesize = max (len , mergeable_ctx_to_buf_truesize (ctx ));
679
670
if (curr_skb != head_skb ) {
680
671
head_skb -> data_len += len ;
681
672
head_skb -> len += len ;
@@ -700,14 +691,14 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
700
691
err_skb :
701
692
put_page (page );
702
693
while (-- num_buf ) {
703
- ctx = ( unsigned long ) virtqueue_get_buf (rq -> vq , & len );
704
- if (unlikely (!ctx )) {
694
+ buf = virtqueue_get_buf (rq -> vq , & len );
695
+ if (unlikely (!buf )) {
705
696
pr_debug ("%s: rx error: %d buffers missing\n" ,
706
697
dev -> name , num_buf );
707
698
dev -> stats .rx_length_errors ++ ;
708
699
break ;
709
700
}
710
- page = virt_to_head_page (mergeable_ctx_to_buf_address ( ctx ) );
701
+ page = virt_to_head_page (buf );
711
702
put_page (page );
712
703
}
713
704
err_buf :
@@ -718,7 +709,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
718
709
}
719
710
720
711
static int receive_buf (struct virtnet_info * vi , struct receive_queue * rq ,
721
- void * buf , unsigned int len )
712
+ void * buf , unsigned int len , void * * ctx )
722
713
{
723
714
struct net_device * dev = vi -> dev ;
724
715
struct sk_buff * skb ;
@@ -729,9 +720,7 @@ static int receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
729
720
pr_debug ("%s: short packet %i\n" , dev -> name , len );
730
721
dev -> stats .rx_length_errors ++ ;
731
722
if (vi -> mergeable_rx_bufs ) {
732
- unsigned long ctx = (unsigned long )buf ;
733
- void * base = mergeable_ctx_to_buf_address (ctx );
734
- put_page (virt_to_head_page (base ));
723
+ put_page (virt_to_head_page (buf ));
735
724
} else if (vi -> big_packets ) {
736
725
give_pages (rq , buf );
737
726
} else {
@@ -741,7 +730,7 @@ static int receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
741
730
}
742
731
743
732
if (vi -> mergeable_rx_bufs )
744
- skb = receive_mergeable (dev , vi , rq , ( unsigned long ) buf , len );
733
+ skb = receive_mergeable (dev , vi , rq , buf , ctx , len );
745
734
else if (vi -> big_packets )
746
735
skb = receive_big (dev , vi , rq , buf , len );
747
736
else
@@ -869,7 +858,7 @@ static int add_recvbuf_mergeable(struct virtnet_info *vi,
869
858
struct page_frag * alloc_frag = & rq -> alloc_frag ;
870
859
unsigned int headroom = virtnet_get_headroom (vi );
871
860
char * buf ;
872
- unsigned long ctx ;
861
+ void * ctx ;
873
862
int err ;
874
863
unsigned int len , hole ;
875
864
@@ -879,7 +868,7 @@ static int add_recvbuf_mergeable(struct virtnet_info *vi,
879
868
880
869
buf = (char * )page_address (alloc_frag -> page ) + alloc_frag -> offset ;
881
870
buf += headroom ; /* advance address leaving hole at front of pkt */
882
- ctx = mergeable_buf_to_ctx ( buf , len ) ;
871
+ ctx = ( void * )( unsigned long ) len ;
883
872
get_page (alloc_frag -> page );
884
873
alloc_frag -> offset += len + headroom ;
885
874
hole = alloc_frag -> size - alloc_frag -> offset ;
@@ -894,7 +883,7 @@ static int add_recvbuf_mergeable(struct virtnet_info *vi,
894
883
}
895
884
896
885
sg_init_one (rq -> sg , buf , len );
897
- err = virtqueue_add_inbuf (rq -> vq , rq -> sg , 1 , ( void * ) ctx , gfp );
886
+ err = virtqueue_add_inbuf_ctx (rq -> vq , rq -> sg , 1 , buf , ctx , gfp );
898
887
if (err < 0 )
899
888
put_page (virt_to_head_page (buf ));
900
889
@@ -988,10 +977,20 @@ static int virtnet_receive(struct receive_queue *rq, int budget)
988
977
void * buf ;
989
978
struct virtnet_stats * stats = this_cpu_ptr (vi -> stats );
990
979
991
- while (received < budget &&
992
- (buf = virtqueue_get_buf (rq -> vq , & len )) != NULL ) {
993
- bytes += receive_buf (vi , rq , buf , len );
994
- received ++ ;
980
+ if (vi -> mergeable_rx_bufs ) {
981
+ void * ctx ;
982
+
983
+ while (received < budget &&
984
+ (buf = virtqueue_get_buf_ctx (rq -> vq , & len , & ctx ))) {
985
+ bytes += receive_buf (vi , rq , buf , len , ctx );
986
+ received ++ ;
987
+ }
988
+ } else {
989
+ while (received < budget &&
990
+ (buf = virtqueue_get_buf (rq -> vq , & len )) != NULL ) {
991
+ bytes += receive_buf (vi , rq , buf , len , NULL );
992
+ received ++ ;
993
+ }
995
994
}
996
995
997
996
if (rq -> vq -> num_free > virtqueue_get_vring_size (rq -> vq ) / 2 ) {
@@ -2014,9 +2013,7 @@ static void free_unused_bufs(struct virtnet_info *vi)
2014
2013
2015
2014
while ((buf = virtqueue_detach_unused_buf (vq )) != NULL ) {
2016
2015
if (vi -> mergeable_rx_bufs ) {
2017
- unsigned long ctx = (unsigned long )buf ;
2018
- void * base = mergeable_ctx_to_buf_address (ctx );
2019
- put_page (virt_to_head_page (base ));
2016
+ put_page (virt_to_head_page (buf ));
2020
2017
} else if (vi -> big_packets ) {
2021
2018
give_pages (& vi -> rq [i ], buf );
2022
2019
} else {
0 commit comments