summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/in6_pcbgroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet6/in6_pcbgroup.c')
-rw-r--r--sys/netinet6/in6_pcbgroup.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/sys/netinet6/in6_pcbgroup.c b/sys/netinet6/in6_pcbgroup.c
index 850d7f4..3e2700c 100644
--- a/sys/netinet6/in6_pcbgroup.c
+++ b/sys/netinet6/in6_pcbgroup.c
@@ -32,35 +32,52 @@
__FBSDID("$FreeBSD$");
#include "opt_inet6.h"
+#include "opt_rss.h"
#include <sys/param.h>
#include <sys/mbuf.h>
#include <netinet/in.h>
#include <netinet/in_pcb.h>
+#include <netinet/in_rss.h>
#ifdef INET6
#include <netinet6/in6_pcb.h>
#endif /* INET6 */
/*
* Given a hash of whatever the covered tuple might be, return a pcbgroup
- * index.
+ * index. Where RSS is supported, try to align bucket selection with RSS CPU
+ * affinity strategy.
*/
static __inline u_int
in6_pcbgroup_getbucket(struct inpcbinfo *pcbinfo, uint32_t hash)
{
+#ifdef RSS
+ return (rss_getbucket(hash));
+#else
return (hash % pcbinfo->ipi_npcbgroups);
+#endif
}
/*
* Map a (hashtype, hash) tuple into a connection group, or NULL if the hash
- * information is insufficient to identify the pcbgroup.
+ * information is insufficient to identify the pcbgroup. This might occur if
+ * a TCP packet turnsup with a 2-tuple hash, or if an RSS hash is present but
+ * RSS is not compiled into the kernel.
*/
struct inpcbgroup *
in6_pcbgroup_byhash(struct inpcbinfo *pcbinfo, u_int hashtype, uint32_t hash)
{
+#ifdef RSS
+ if ((pcbinfo->ipi_hashfields == IPI_HASHFIELDS_4TUPLE &&
+ hashtype == M_HASHTYPE_RSS_TCP_IPV4) ||
+ (pcbinfo->ipi_hashfields == IPI_HASHFIELDS_2TUPLE &&
+ hashtype == M_HASHTYPE_RSS_IPV4))
+ return (&pcbinfo->ipi_pcbgroups[
+ in6_pcbgroup_getbucket(pcbinfo, hash)]);
+#endif
return (NULL);
}
@@ -78,13 +95,26 @@ in6_pcbgroup_bytuple(struct inpcbinfo *pcbinfo, const struct in6_addr *laddrp,
{
uint32_t hash;
+ /*
+ * RSS note: we pass foreign addr/port as source, and local addr/port
+ * as destination, as we want to align with what the hardware is
+ * doing.
+ */
switch (pcbinfo->ipi_hashfields) {
case IPI_HASHFIELDS_4TUPLE:
+#ifdef RSS
+ hash = rss_hash_ip6_4tuple(*faddrp, fport, *laddrp, lport);
+#else
hash = faddrp->s6_addr32[3] ^ fport;
+#endif
break;
case IPI_HASHFIELDS_2TUPLE:
+#ifdef RSS
+ hash = rss_hash_ip6_2tuple(*faddrp, *laddrp);
+#else
hash = faddrp->s6_addr32[3] ^ laddrp->s6_addr32[3];
+#endif
break;
default:
OpenPOWER on IntegriCloud