7474 (1ULL << VHOST_NET_F_VIRTIO_NET_HDR ) |
7575 (1ULL << VIRTIO_NET_F_MRG_RXBUF ) |
7676 (1ULL << VIRTIO_F_ACCESS_PLATFORM ) |
77- (1ULL << VIRTIO_F_RING_RESET )
77+ (1ULL << VIRTIO_F_RING_RESET ) |
78+ (1ULL << VIRTIO_F_IN_ORDER )
7879};
7980
8081enum {
@@ -450,16 +451,17 @@ static int vhost_net_enable_vq(struct vhost_net *n,
450451 return vhost_poll_start (poll , sock -> file );
451452}
452453
453- static void vhost_net_signal_used (struct vhost_net_virtqueue * nvq )
454+ static void vhost_net_signal_used (struct vhost_net_virtqueue * nvq ,
455+ unsigned int count )
454456{
455457 struct vhost_virtqueue * vq = & nvq -> vq ;
456458 struct vhost_dev * dev = vq -> dev ;
457459
458460 if (!nvq -> done_idx )
459461 return ;
460462
461- vhost_add_used_and_signal_n (dev , vq , vq -> heads , NULL ,
462- nvq -> done_idx );
463+ vhost_add_used_and_signal_n (dev , vq , vq -> heads ,
464+ vq -> nheads , count );
463465 nvq -> done_idx = 0 ;
464466}
465467
@@ -468,13 +470,20 @@ static void vhost_tx_batch(struct vhost_net *net,
468470 struct socket * sock ,
469471 struct msghdr * msghdr )
470472{
473+ struct vhost_virtqueue * vq = & nvq -> vq ;
474+ bool in_order = vhost_has_feature (vq , VIRTIO_F_IN_ORDER );
471475 struct tun_msg_ctl ctl = {
472476 .type = TUN_MSG_PTR ,
473477 .num = nvq -> batched_xdp ,
474478 .ptr = nvq -> xdp ,
475479 };
476480 int i , err ;
477481
482+ if (in_order ) {
483+ vq -> heads [0 ].len = 0 ;
484+ vq -> nheads [0 ] = nvq -> done_idx ;
485+ }
486+
478487 if (nvq -> batched_xdp == 0 )
479488 goto signal_used ;
480489
@@ -496,7 +505,7 @@ static void vhost_tx_batch(struct vhost_net *net,
496505 }
497506
498507signal_used :
499- vhost_net_signal_used (nvq );
508+ vhost_net_signal_used (nvq , in_order ? 1 : nvq -> done_idx );
500509 nvq -> batched_xdp = 0 ;
501510}
502511
@@ -758,6 +767,7 @@ static void handle_tx_copy(struct vhost_net *net, struct socket *sock)
758767 int sent_pkts = 0 ;
759768 bool sock_can_batch = (sock -> sk -> sk_sndbuf == INT_MAX );
760769 bool busyloop_intr ;
770+ bool in_order = vhost_has_feature (vq , VIRTIO_F_IN_ORDER );
761771
762772 do {
763773 busyloop_intr = false;
@@ -794,11 +804,13 @@ static void handle_tx_copy(struct vhost_net *net, struct socket *sock)
794804 break ;
795805 }
796806
797- /* We can't build XDP buff, go for single
798- * packet path but let's flush batched
799- * packets.
800- */
801- vhost_tx_batch (net , nvq , sock , & msg );
807+ if (nvq -> batched_xdp ) {
808+ /* We can't build XDP buff, go for single
809+ * packet path but let's flush batched
810+ * packets.
811+ */
812+ vhost_tx_batch (net , nvq , sock , & msg );
813+ }
802814 msg .msg_control = NULL ;
803815 } else {
804816 if (tx_can_batch (vq , total_len ))
@@ -819,8 +831,12 @@ static void handle_tx_copy(struct vhost_net *net, struct socket *sock)
819831 pr_debug ("Truncated TX packet: len %d != %zd\n" ,
820832 err , len );
821833done :
822- vq -> heads [nvq -> done_idx ].id = cpu_to_vhost32 (vq , head );
823- vq -> heads [nvq -> done_idx ].len = 0 ;
834+ if (in_order ) {
835+ vq -> heads [0 ].id = cpu_to_vhost32 (vq , head );
836+ } else {
837+ vq -> heads [nvq -> done_idx ].id = cpu_to_vhost32 (vq , head );
838+ vq -> heads [nvq -> done_idx ].len = 0 ;
839+ }
824840 ++ nvq -> done_idx ;
825841 } while (likely (!vhost_exceeds_weight (vq , ++ sent_pkts , total_len )));
826842
@@ -999,7 +1015,7 @@ static int peek_head_len(struct vhost_net_virtqueue *rvq, struct sock *sk)
9991015}
10001016
10011017static int vhost_net_rx_peek_head_len (struct vhost_net * net , struct sock * sk ,
1002- bool * busyloop_intr )
1018+ bool * busyloop_intr , unsigned int count )
10031019{
10041020 struct vhost_net_virtqueue * rnvq = & net -> vqs [VHOST_NET_VQ_RX ];
10051021 struct vhost_net_virtqueue * tnvq = & net -> vqs [VHOST_NET_VQ_TX ];
@@ -1009,7 +1025,7 @@ static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk,
10091025
10101026 if (!len && rvq -> busyloop_timeout ) {
10111027 /* Flush batched heads first */
1012- vhost_net_signal_used (rnvq );
1028+ vhost_net_signal_used (rnvq , count );
10131029 /* Both tx vq and rx socket were polled here */
10141030 vhost_net_busy_poll (net , rvq , tvq , busyloop_intr , true);
10151031
@@ -1021,22 +1037,25 @@ static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk,
10211037
10221038/* This is a multi-buffer version of vhost_get_desc, that works if
10231039 * vq has read descriptors only.
1024- * @vq - the relevant virtqueue
1040+ * @nvq - the relevant vhost_net virtqueue
10251041 * @datalen - data length we'll be reading
10261042 * @iovcount - returned count of io vectors we fill
10271043 * @log - vhost log
10281044 * @log_num - log offset
10291045 * @quota - headcount quota, 1 for big buffer
10301046 * returns number of buffer heads allocated, negative on error
10311047 */
1032- static int get_rx_bufs (struct vhost_virtqueue * vq ,
1048+ static int get_rx_bufs (struct vhost_net_virtqueue * nvq ,
10331049 struct vring_used_elem * heads ,
1050+ u16 * nheads ,
10341051 int datalen ,
10351052 unsigned * iovcount ,
10361053 struct vhost_log * log ,
10371054 unsigned * log_num ,
10381055 unsigned int quota )
10391056{
1057+ struct vhost_virtqueue * vq = & nvq -> vq ;
1058+ bool in_order = vhost_has_feature (vq , VIRTIO_F_IN_ORDER );
10401059 unsigned int out , in ;
10411060 int seg = 0 ;
10421061 int headcount = 0 ;
@@ -1073,14 +1092,16 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
10731092 nlogs += * log_num ;
10741093 log += * log_num ;
10751094 }
1076- heads [headcount ].id = cpu_to_vhost32 (vq , d );
10771095 len = iov_length (vq -> iov + seg , in );
1078- heads [headcount ].len = cpu_to_vhost32 (vq , len );
1079- datalen -= len ;
1096+ if (!in_order ) {
1097+ heads [headcount ].id = cpu_to_vhost32 (vq , d );
1098+ heads [headcount ].len = cpu_to_vhost32 (vq , len );
1099+ }
10801100 ++ headcount ;
1101+ datalen -= len ;
10811102 seg += in ;
10821103 }
1083- heads [ headcount - 1 ]. len = cpu_to_vhost32 ( vq , len + datalen );
1104+
10841105 * iovcount = seg ;
10851106 if (unlikely (log ))
10861107 * log_num = nlogs ;
@@ -1090,6 +1111,15 @@ static int get_rx_bufs(struct vhost_virtqueue *vq,
10901111 r = UIO_MAXIOV + 1 ;
10911112 goto err ;
10921113 }
1114+
1115+ if (!in_order )
1116+ heads [headcount - 1 ].len = cpu_to_vhost32 (vq , len + datalen );
1117+ else {
1118+ heads [0 ].len = cpu_to_vhost32 (vq , len + datalen );
1119+ heads [0 ].id = cpu_to_vhost32 (vq , d );
1120+ nheads [0 ] = headcount ;
1121+ }
1122+
10931123 return headcount ;
10941124err :
10951125 vhost_discard_vq_desc (vq , headcount );
@@ -1102,6 +1132,8 @@ static void handle_rx(struct vhost_net *net)
11021132{
11031133 struct vhost_net_virtqueue * nvq = & net -> vqs [VHOST_NET_VQ_RX ];
11041134 struct vhost_virtqueue * vq = & nvq -> vq ;
1135+ bool in_order = vhost_has_feature (vq , VIRTIO_F_IN_ORDER );
1136+ unsigned int count = 0 ;
11051137 unsigned in , log ;
11061138 struct vhost_log * vq_log ;
11071139 struct msghdr msg = {
@@ -1149,12 +1181,13 @@ static void handle_rx(struct vhost_net *net)
11491181
11501182 do {
11511183 sock_len = vhost_net_rx_peek_head_len (net , sock -> sk ,
1152- & busyloop_intr );
1184+ & busyloop_intr , count );
11531185 if (!sock_len )
11541186 break ;
11551187 sock_len += sock_hlen ;
11561188 vhost_len = sock_len + vhost_hlen ;
1157- headcount = get_rx_bufs (vq , vq -> heads + nvq -> done_idx ,
1189+ headcount = get_rx_bufs (nvq , vq -> heads + count ,
1190+ vq -> nheads + count ,
11581191 vhost_len , & in , vq_log , & log ,
11591192 likely (mergeable ) ? UIO_MAXIOV : 1 );
11601193 /* On error, stop handling until the next kick. */
@@ -1230,8 +1263,11 @@ static void handle_rx(struct vhost_net *net)
12301263 goto out ;
12311264 }
12321265 nvq -> done_idx += headcount ;
1233- if (nvq -> done_idx > VHOST_NET_BATCH )
1234- vhost_net_signal_used (nvq );
1266+ count += in_order ? 1 : headcount ;
1267+ if (nvq -> done_idx > VHOST_NET_BATCH ) {
1268+ vhost_net_signal_used (nvq , count );
1269+ count = 0 ;
1270+ }
12351271 if (unlikely (vq_log ))
12361272 vhost_log_write (vq , vq_log , log , vhost_len ,
12371273 vq -> iov , in );
@@ -1243,7 +1279,7 @@ static void handle_rx(struct vhost_net *net)
12431279 else if (!sock_len )
12441280 vhost_net_enable_vq (net , vq );
12451281out :
1246- vhost_net_signal_used (nvq );
1282+ vhost_net_signal_used (nvq , count );
12471283 mutex_unlock (& vq -> mutex );
12481284}
12491285
0 commit comments