static int ether_ipfw;
static u_long ether_restore_hdr;
static u_long ether_prepend_hdr;
+static u_long ether_input_wronghash;
static int ether_debug;
#ifdef RSS_DEBUG
static u_long ether_pktinfo_hit;
static u_long ether_rss_nopi;
static u_long ether_rss_nohash;
+static u_long ether_input_requeue;
#endif
SYSCTL_DECL(_net_link);
SYSCTL_ULONG(_net_link_ether, OID_AUTO, prepend_hdr, CTLFLAG_RW,
ðer_prepend_hdr, 0,
"# of ether header restoration which prepends mbuf");
+SYSCTL_ULONG(_net_link_ether, OID_AUTO, input_wronghash, CTLFLAG_RW,
+ ðer_input_wronghash, 0, "# of input packets with wrong hash");
#ifdef RSS_DEBUG
SYSCTL_ULONG(_net_link_ether, OID_AUTO, rss_nopi, CTLFLAG_RW,
ðer_rss_nopi, 0, "# of packets do not have pktinfo");
SYSCTL_ULONG(_net_link_ether, OID_AUTO, pktinfo_hit, CTLFLAG_RW,
ðer_pktinfo_hit, 0,
"# of packets whose msgport are found using pktinfo");
+SYSCTL_ULONG(_net_link_ether, OID_AUTO, input_requeue, CTLFLAG_RW,
+ ðer_input_requeue, 0, "# of input packets gets requeued");
#endif
#define ETHER_KTR_STR "ifp=%p"
default:
/*
* The accurate msgport is not determined before
- * we reach here, so redo the dispatching
+ * we reach here, so recharacterize packet.
*/
+ m->m_flags &= ~M_HASH;
#ifdef IPX
if (ef_inputp) {
/*
return;
}
+ if (m->m_flags & M_HASH) {
+ if (&curthread->td_msgport == cpu_portfn(m->m_pkthdr.hash)) {
+ netisr_handle(isr, m);
+ return;
+ } else {
+ /*
+ * XXX Something is wrong,
+ * we probably should panic here!
+ */
+ m->m_flags &= ~M_HASH;
+ ether_input_wronghash++;
+ }
+ }
+#ifdef RSS_DEBUG
+ ether_input_requeue++;
+#endif
netisr_queue(isr, m);
}
}
/*
+ * Run a netisr service function on the packet.
+ *
+ * The packet must have been correctly characterized!
+ */
+int
+netisr_handle(int num, struct mbuf *m)
+{
+ struct netisr *ni;
+ struct netmsg_packet *pmsg;
+ lwkt_port_t port;
+
+ /*
+ * Get the protocol port based on the packet hash
+ */
+ KASSERT((m->m_flags & M_HASH), ("packet not characterized\n"));
+ port = cpu_portfn(m->m_pkthdr.hash);
+ KASSERT(&curthread->td_msgport == port, ("wrong msgport\n"));
+
+ KASSERT((num > 0 && num <= NELEM(netisrs)), ("bad isr %d", num));
+ ni = &netisrs[num];
+ if (ni->ni_handler == NULL) {
+ kprintf("unregistered isr %d\n", num);
+ m_freem(m);
+ return EIO;
+ }
+
+ /*
+ * Initialize the netmsg, and run the handler directly.
+ */
+ pmsg = &m->m_hdr.mh_netmsg;
+ netmsg_init(&pmsg->base, NULL, &netisr_apanic_rport,
+ 0, ni->ni_handler);
+ pmsg->nm_packet = m;
+ pmsg->base.lmsg.u.ms_result = num;
+ ni->ni_handler((netmsg_t)&pmsg->base);
+
+ return 0;
+}
+
+/*
* Pre-characterization of a deeper portion of the packet for the
* requested isr.
*
void netisr_hashcheck(int num, struct mbuf *m,
const struct pktinfo *pi);
int netisr_queue(int, struct mbuf *);
+int netisr_handle(int, struct mbuf *);
struct netisr_barrier *netisr_barrier_create(void);
void netisr_barrier_set(struct netisr_barrier *);