Skip to content

Commit

Permalink
dpif-netdev: Check for PKT_RX_RSS_HASH flag.
Browse files Browse the repository at this point in the history
DPDK mbufs contain a valid RSS hash only if PKT_RX_RSS_HASH is
set in 'ol_flags'.  Otherwise the hash is garbage and doesn't
relate to the packet.

This fixes an issue with vhost, which, being a virtual NIC, doesn't
compute the hash.

Reported-by: Dongjun <[email protected]>
Suggested-by: Flavio Leitner <[email protected]>
Acked-by: Kevin Traynor <[email protected]>
Acked-by: Pravin B Shelar <[email protected]>
Signed-off-by: Daniele Di Proietto <[email protected]>
  • Loading branch information
ddiproietto committed Sep 11, 2015
1 parent 8f96455 commit f2f44f5
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 6 deletions.
25 changes: 25 additions & 0 deletions lib/dp-packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ struct dp_packet {
uint16_t data_ofs; /* First byte actually in use. */
uint32_t size_; /* Number of bytes in use. */
uint32_t rss_hash; /* Packet hash. */
bool rss_hash_valid; /* Is the 'rss_hash' valid? */
#endif
enum dp_packet_source source; /* Source of memory allocated as 'base'. */
uint8_t l2_pad_size; /* Detected l2 padding size.
Expand Down Expand Up @@ -514,6 +515,8 @@ dp_packet_reset_packet(struct dp_packet *b, int off)
b->l2_5_ofs = b->l3_ofs = b->l4_ofs = UINT16_MAX;
}

/* Returns the RSS hash of the packet 'p'. Note that the returned value is
* correct only if 'dp_packet_rss_valid(p)' returns true */
static inline uint32_t
dp_packet_get_rss_hash(struct dp_packet *p)
{
Expand All @@ -529,8 +532,30 @@ dp_packet_set_rss_hash(struct dp_packet *p, uint32_t hash)
{
#ifdef DPDK_NETDEV
p->mbuf.hash.rss = hash;
p->mbuf.ol_flags |= PKT_RX_RSS_HASH;
#else
p->rss_hash = hash;
p->rss_hash_valid = true;
#endif
}

static inline bool
dp_packet_rss_valid(struct dp_packet *p)
{
#ifdef DPDK_NETDEV
return p->mbuf.ol_flags & PKT_RX_RSS_HASH;
#else
return p->rss_hash_valid;
#endif
}

static inline void
dp_packet_rss_invalidate(struct dp_packet *p)
{
#ifdef DPDK_NETDEV
p->mbuf.ol_flags &= ~PKT_RX_RSS_HASH;
#else
p->rss_hash_valid = false;
#endif
}

Expand Down
5 changes: 3 additions & 2 deletions lib/dpif-netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -3100,8 +3100,9 @@ dpif_netdev_packet_get_rss_hash(struct dp_packet *packet,
{
uint32_t hash, recirc_depth;

hash = dp_packet_get_rss_hash(packet);
if (OVS_UNLIKELY(!hash)) {
if (OVS_LIKELY(dp_packet_rss_valid(packet))) {
hash = dp_packet_get_rss_hash(packet);
} else {
hash = miniflow_hash_5tuple(mf, 0);
dp_packet_set_rss_hash(packet, hash);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/netdev-bsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ netdev_bsd_rxq_recv(struct netdev_rxq *rxq_, struct dp_packet **packets,
dp_packet_delete(packet);
} else {
dp_packet_pad(packet);
dp_packet_set_rss_hash(packet, 0);
dp_packet_rss_invalidate(packet);
packets[0] = packet;
*c = 1;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/netdev-dpdk.c
Original file line number Diff line number Diff line change
Expand Up @@ -2001,7 +2001,7 @@ netdev_dpdk_ring_send(struct netdev *netdev_, int qid,
* the consumer of the ring and return into the datapath without recalculating
* the RSS hash. */
for (i = 0; i < cnt; i++) {
dp_packet_set_rss_hash(pkts[i], 0);
dp_packet_rss_invalidate(pkts[i]);
}

netdev_dpdk_send__(netdev, qid, pkts, cnt, may_steal);
Expand Down
2 changes: 1 addition & 1 deletion lib/netdev-dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ netdev_dummy_rxq_recv(struct netdev_rxq *rxq_, struct dp_packet **arr,
ovs_mutex_unlock(&netdev->mutex);

dp_packet_pad(packet);
dp_packet_set_rss_hash(packet, 0);
dp_packet_rss_invalidate(packet);

arr[0] = packet;
*c = 1;
Expand Down
2 changes: 1 addition & 1 deletion lib/netdev-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,7 @@ netdev_linux_rxq_recv(struct netdev_rxq *rxq_, struct dp_packet **packets,
dp_packet_delete(buffer);
} else {
dp_packet_pad(buffer);
dp_packet_set_rss_hash(buffer, 0);
dp_packet_rss_invalidate(buffer);
packets[0] = buffer;
*c = 1;
}
Expand Down

0 comments on commit f2f44f5

Please sign in to comment.