/* * Similar to rss_m2cpuid, but designed to be used by the IP NETISR * on incoming frames. * * If an existing RSS hash exists and it matches what the configured * hashing is, then use it. * * If there's an existing RSS hash but the desired hash is different, * or if there's no useful RSS hash, then calculate it via * the software path. * * XXX TODO: definitely want statistics here! */ struct mbuf * rss_soft_m2cpuid(struct mbuf *m, uintptr_t source, u_int *cpuid) { uint32_t hash_val, hash_type; int ret; M_ASSERTPKTHDR(m); ret = rss_mbuf_software_hash_v4(m, RSS_HASH_PKT_INGRESS, &hash_val, &hash_type); if (ret > 0) { /* mbuf has a valid hash already; don't need to modify it */ *cpuid = rss_hash2cpuid(m->m_pkthdr.flowid, M_HASHTYPE_GET(m)); } else if (ret == 0) { /* hash was done; update */ m->m_pkthdr.flowid = hash_val; M_HASHTYPE_SET(m, hash_type); m->m_flags |= M_FLOWID; *cpuid = rss_hash2cpuid(m->m_pkthdr.flowid, M_HASHTYPE_GET(m)); } else { /* ret < 0 */ /* no hash was done */ *cpuid = NETISR_CPUID_NONE; } return (m); }
/* * Map the given inp to a CPU id. * * This queries RSS if it's compiled in, else it defaults to the current * CPU ID. */ static inline int inp_to_cpuid(struct inpcb *inp) { u_int cpuid; #ifdef RSS if (per_cpu_timers) { cpuid = rss_hash2cpuid(inp->inp_flowid, inp->inp_flowtype); if (cpuid == NETISR_CPUID_NONE) return (curcpu); /* XXX */ else return (cpuid); } #else /* Legacy, pre-RSS behaviour */ if (per_cpu_timers) { /* * We don't have a flowid -> cpuid mapping, so cheat and * just map unknown cpuids to curcpu. Not the best, but * apparently better than defaulting to swi 0. */ cpuid = inp->inp_flowid % (mp_maxid + 1); if (! CPU_ABSENT(cpuid)) return (cpuid); return (curcpu); } #endif /* Default for RSS and non-RSS - cpuid 0 */ else { return (0); } }
/* * netisr CPU affinity lookup routine for use by protocols. */ struct mbuf * rss_m2cpuid(struct mbuf *m, uintptr_t source, u_int *cpuid) { M_ASSERTPKTHDR(m); *cpuid = rss_hash2cpuid(m->m_pkthdr.flowid, M_HASHTYPE_GET(m)); return (m); }