/* * netisr CPU affinity lookup given just the hash and hashtype. */ u_int rss_hash2cpuid(uint32_t hash_val, uint32_t hash_type) { switch (hash_type) { case M_HASHTYPE_RSS_IPV4: case M_HASHTYPE_RSS_TCP_IPV4: return (rss_getcpu(rss_getbucket(hash_val))); default: return (NETISR_CPUID_NONE); } }
static int sysctl_rss_bucket_mapping(SYSCTL_HANDLER_ARGS) { struct sbuf *sb; int error; int i; error = 0; error = sysctl_wire_old_buffer(req, 0); if (error != 0) return (error); sb = sbuf_new_for_sysctl(NULL, NULL, 512, req); if (sb == NULL) return (ENOMEM); for (i = 0; i < rss_buckets; i++) { sbuf_printf(sb, "%s%d:%d", i == 0 ? "" : " ", i, rss_getcpu(i)); } error = sbuf_finish(sb); sbuf_delete(sb); return (error); }
void in_pcbgroup_init(struct inpcbinfo *pcbinfo, u_int hashfields, int hash_nelements) { struct inpcbgroup *pcbgroup; u_int numpcbgroups, pgn; /* * Only enable connection groups for a protocol if it has been * specifically requested. */ if (hashfields == IPI_HASHFIELDS_NONE) return; /* * Connection groups are about multi-processor load distribution, * lock contention, and connection CPU affinity. As such, no point * in turning them on for a uniprocessor machine, it only wastes * memory. */ if (mp_ncpus == 1) return; #ifdef RSS /* * If we're using RSS, then RSS determines the number of connection * groups to use: one connection group per RSS bucket. If for some * reason RSS isn't able to provide a number of buckets, disable * connection groups entirely. * * XXXRW: Can this ever happen? */ numpcbgroups = rss_getnumbuckets(); if (numpcbgroups == 0) return; #else /* * Otherwise, we'll just use one per CPU for now. If we decide to * do dynamic rebalancing a la RSS, we'll need similar logic here. */ numpcbgroups = mp_ncpus; #endif pcbinfo->ipi_hashfields = hashfields; pcbinfo->ipi_pcbgroups = malloc(numpcbgroups * sizeof(*pcbinfo->ipi_pcbgroups), M_PCB, M_WAITOK | M_ZERO); pcbinfo->ipi_npcbgroups = numpcbgroups; pcbinfo->ipi_wildbase = hashinit(hash_nelements, M_PCB, &pcbinfo->ipi_wildmask); for (pgn = 0; pgn < pcbinfo->ipi_npcbgroups; pgn++) { pcbgroup = &pcbinfo->ipi_pcbgroups[pgn]; pcbgroup->ipg_hashbase = hashinit(hash_nelements, M_PCB, &pcbgroup->ipg_hashmask); INP_GROUP_LOCK_INIT(pcbgroup, "pcbgroup"); /* * Initialise notional affinity of the pcbgroup -- for RSS, * we want the same notion of affinity as NICs to be used. In * the non-RSS case, just round robin for the time being. * * XXXRW: The notion of a bucket to CPU mapping is common at * both pcbgroup and RSS layers -- does that mean that we * should migrate it all from RSS to here, and just leave RSS * responsible only for providing hashing and mapping funtions? */ #ifdef RSS pcbgroup->ipg_cpu = rss_getcpu(pgn); #else pcbgroup->ipg_cpu = (pgn % mp_ncpus); #endif } }