Skip to content

Commit 8db91f6

Browse files
haiyangzdavem330
authored andcommitted
hv_netvsc: Fix the queue index computation in forwarding case
If the outgoing skb has a RX queue mapping available, we use the queue number directly, other than put it through Send Indirection Table. Signed-off-by: Haiyang Zhang <[email protected]> Reviewed-by: Stephen Hemminger <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent a6a71f1 commit 8db91f6

File tree

2 files changed

+31
-15
lines changed

2 files changed

+31
-15
lines changed

drivers/net/hyperv/hyperv_net.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ struct nvsp_message {
633633

634634
#define NETVSC_PACKET_SIZE 4096
635635

636-
#define VRSS_SEND_TAB_SIZE 16
636+
#define VRSS_SEND_TAB_SIZE 16 /* must be power of 2 */
637637
#define VRSS_CHANNEL_MAX 64
638638
#define VRSS_CHANNEL_DEFAULT 8
639639

drivers/net/hyperv/netvsc_drv.c

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,24 @@ static void *init_ppi_data(struct rndis_message *msg, u32 ppi_size,
191191
return ppi;
192192
}
193193

194+
static inline int netvsc_get_tx_queue(struct net_device *ndev,
195+
struct sk_buff *skb, int old_idx)
196+
{
197+
const struct net_device_context *ndc = netdev_priv(ndev);
198+
struct sock *sk = skb->sk;
199+
int q_idx;
200+
201+
q_idx = ndc->tx_send_table[skb_get_hash(skb) &
202+
(VRSS_SEND_TAB_SIZE - 1)];
203+
204+
/* If queue index changed record the new value */
205+
if (q_idx != old_idx &&
206+
sk && sk_fullsock(sk) && rcu_access_pointer(sk->sk_dst_cache))
207+
sk_tx_queue_set(sk, q_idx);
208+
209+
return q_idx;
210+
}
211+
194212
/*
195213
* Select queue for transmit.
196214
*
@@ -205,24 +223,22 @@ static void *init_ppi_data(struct rndis_message *msg, u32 ppi_size,
205223
static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
206224
void *accel_priv, select_queue_fallback_t fallback)
207225
{
208-
struct net_device_context *net_device_ctx = netdev_priv(ndev);
209226
unsigned int num_tx_queues = ndev->real_num_tx_queues;
210-
struct sock *sk = skb->sk;
211-
int q_idx = sk_tx_queue_get(sk);
212-
213-
if (q_idx < 0 || skb->ooo_okay || q_idx >= num_tx_queues) {
214-
u16 hash = __skb_tx_hash(ndev, skb, VRSS_SEND_TAB_SIZE);
215-
int new_idx;
216-
217-
new_idx = net_device_ctx->tx_send_table[hash] % num_tx_queues;
227+
int q_idx = sk_tx_queue_get(skb->sk);
218228

219-
if (q_idx != new_idx && sk &&
220-
sk_fullsock(sk) && rcu_access_pointer(sk->sk_dst_cache))
221-
sk_tx_queue_set(sk, new_idx);
222-
223-
q_idx = new_idx;
229+
if (q_idx < 0 || skb->ooo_okay) {
230+
/* If forwarding a packet, we use the recorded queue when
231+
* available for better cache locality.
232+
*/
233+
if (skb_rx_queue_recorded(skb))
234+
q_idx = skb_get_rx_queue(skb);
235+
else
236+
q_idx = netvsc_get_tx_queue(ndev, skb, q_idx);
224237
}
225238

239+
while (unlikely(q_idx >= num_tx_queues))
240+
q_idx -= num_tx_queues;
241+
226242
return q_idx;
227243
}
228244

0 commit comments

Comments
 (0)