svn commit: r185473 - head/sys/dev/xen/netfront
Doug Rabson
dfr at FreeBSD.org
Sun Nov 30 04:21:49 PST 2008
Author: dfr
Date: Sun Nov 30 12:21:46 2008
New Revision: 185473
URL: http://svn.freebsd.org/changeset/base/185473
Log:
Don't call ether_ioctl() with locks held. Loop in xn_rxeof() until the backend
stops adding stuff to the ring otherwise we miss RX interrupts which kills
performance.
Modified:
head/sys/dev/xen/netfront/netfront.c
Modified: head/sys/dev/xen/netfront/netfront.c
==============================================================================
--- head/sys/dev/xen/netfront/netfront.c Sun Nov 30 11:03:16 2008 (r185472)
+++ head/sys/dev/xen/netfront/netfront.c Sun Nov 30 12:21:46 2008 (r185473)
@@ -855,110 +855,112 @@ xn_rxeof(struct netfront_info *np)
multicall_entry_t *mcl;
struct mbuf *m;
struct mbuf_head rxq, errq;
- int err, pages_flipped = 0;
+ int err, pages_flipped = 0, work_to_do;
- XN_RX_LOCK_ASSERT(np);
- if (!netfront_carrier_ok(np))
- return;
+ do {
+ XN_RX_LOCK_ASSERT(np);
+ if (!netfront_carrier_ok(np))
+ return;
- mbufq_init(&errq);
- mbufq_init(&rxq);
+ mbufq_init(&errq);
+ mbufq_init(&rxq);
- ifp = np->xn_ifp;
+ ifp = np->xn_ifp;
- rp = np->rx.sring->rsp_prod;
- rmb(); /* Ensure we see queued responses up to 'rp'. */
+ rp = np->rx.sring->rsp_prod;
+ rmb(); /* Ensure we see queued responses up to 'rp'. */
+
+ i = np->rx.rsp_cons;
+ while ((i != rp)) {
+ memcpy(rx, RING_GET_RESPONSE(&np->rx, i), sizeof(*rx));
+ memset(extras, 0, sizeof(rinfo.extras));
- i = np->rx.rsp_cons;
- while ((i != rp)) {
- memcpy(rx, RING_GET_RESPONSE(&np->rx, i), sizeof(*rx));
- memset(extras, 0, sizeof(rinfo.extras));
-
- m = NULL;
- err = xennet_get_responses(np, &rinfo, rp, &m,
- &pages_flipped);
+ m = NULL;
+ err = xennet_get_responses(np, &rinfo, rp, &m,
+ &pages_flipped);
- if (unlikely(err)) {
+ if (unlikely(err)) {
if (m)
- mbufq_tail(&errq, m);
- np->stats.rx_errors++;
- i = np->rx.rsp_cons;
- continue;
- }
+ mbufq_tail(&errq, m);
+ np->stats.rx_errors++;
+ i = np->rx.rsp_cons;
+ continue;
+ }
- m->m_pkthdr.rcvif = ifp;
- if ( rx->flags & NETRXF_data_validated ) {
- /* Tell the stack the checksums are okay */
- /*
- * XXX this isn't necessarily the case - need to add
- * check
- */
+ m->m_pkthdr.rcvif = ifp;
+ if ( rx->flags & NETRXF_data_validated ) {
+ /* Tell the stack the checksums are okay */
+ /*
+ * XXX this isn't necessarily the case - need to add
+ * check
+ */
- m->m_pkthdr.csum_flags |=
- (CSUM_IP_CHECKED | CSUM_IP_VALID | CSUM_DATA_VALID
- | CSUM_PSEUDO_HDR);
- m->m_pkthdr.csum_data = 0xffff;
- }
+ m->m_pkthdr.csum_flags |=
+ (CSUM_IP_CHECKED | CSUM_IP_VALID | CSUM_DATA_VALID
+ | CSUM_PSEUDO_HDR);
+ m->m_pkthdr.csum_data = 0xffff;
+ }
- np->stats.rx_packets++;
- np->stats.rx_bytes += m->m_pkthdr.len;
+ np->stats.rx_packets++;
+ np->stats.rx_bytes += m->m_pkthdr.len;
- mbufq_tail(&rxq, m);
- np->rx.rsp_cons = ++i;
- }
+ mbufq_tail(&rxq, m);
+ np->rx.rsp_cons = ++i;
+ }
- if (pages_flipped) {
- /* Some pages are no longer absent... */
+ if (pages_flipped) {
+ /* Some pages are no longer absent... */
#ifdef notyet
- balloon_update_driver_allowance(-pages_flipped);
+ balloon_update_driver_allowance(-pages_flipped);
#endif
- /* Do all the remapping work, and M->P updates, in one big
- * hypercall.
- */
- if (!!xen_feature(XENFEAT_auto_translated_physmap)) {
- mcl = np->rx_mcl + pages_flipped;
- mcl->op = __HYPERVISOR_mmu_update;
- mcl->args[0] = (u_long)np->rx_mmu;
- mcl->args[1] = pages_flipped;
- mcl->args[2] = 0;
- mcl->args[3] = DOMID_SELF;
- (void)HYPERVISOR_multicall(np->rx_mcl,
- pages_flipped + 1);
+ /* Do all the remapping work, and M->P updates, in one big
+ * hypercall.
+ */
+ if (!!xen_feature(XENFEAT_auto_translated_physmap)) {
+ mcl = np->rx_mcl + pages_flipped;
+ mcl->op = __HYPERVISOR_mmu_update;
+ mcl->args[0] = (u_long)np->rx_mmu;
+ mcl->args[1] = pages_flipped;
+ mcl->args[2] = 0;
+ mcl->args[3] = DOMID_SELF;
+ (void)HYPERVISOR_multicall(np->rx_mcl,
+ pages_flipped + 1);
+ }
}
- }
- while ((m = mbufq_dequeue(&errq)))
- m_freem(m);
-
- /*
- * Process all the mbufs after the remapping is complete.
- * Break the mbuf chain first though.
- */
- while ((m = mbufq_dequeue(&rxq)) != NULL) {
- ifp->if_ipackets++;
-
- /*
- * Do we really need to drop the rx lock?
+ while ((m = mbufq_dequeue(&errq)))
+ m_freem(m);
+
+ /*
+ * Process all the mbufs after the remapping is complete.
+ * Break the mbuf chain first though.
*/
- XN_RX_UNLOCK(np);
- /* Pass it up. */
- (*ifp->if_input)(ifp, m);
- XN_RX_LOCK(np);
- }
+ while ((m = mbufq_dequeue(&rxq)) != NULL) {
+ ifp->if_ipackets++;
+
+ /*
+ * Do we really need to drop the rx lock?
+ */
+ XN_RX_UNLOCK(np);
+ /* Pass it up. */
+ (*ifp->if_input)(ifp, m);
+ XN_RX_LOCK(np);
+ }
- np->rx.rsp_cons = i;
+ np->rx.rsp_cons = i;
#if 0
- /* If we get a callback with very few responses, reduce fill target. */
- /* NB. Note exponential increase, linear decrease. */
- if (((np->rx.req_prod_pvt - np->rx.sring->rsp_prod) >
- ((3*np->rx_target) / 4)) && (--np->rx_target < np->rx_min_target))
- np->rx_target = np->rx_min_target;
+ /* If we get a callback with very few responses, reduce fill target. */
+ /* NB. Note exponential increase, linear decrease. */
+ if (((np->rx.req_prod_pvt - np->rx.sring->rsp_prod) >
+ ((3*np->rx_target) / 4)) && (--np->rx_target < np->rx_min_target))
+ np->rx_target = np->rx_min_target;
#endif
- network_alloc_rx_buffers(np);
+ network_alloc_rx_buffers(np);
- np->rx.sring->rsp_event = i + 1;
+ RING_FINAL_CHECK_FOR_RESPONSES(&np->rx, work_to_do);
+ } while (work_to_do);
}
static void
@@ -1437,9 +1439,11 @@ xn_ioctl(struct ifnet *ifp, u_long cmd,
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
xn_ifinit_locked(sc);
arp_ifinit(ifp, ifa);
- } else
+ XN_UNLOCK(sc);
+ } else {
+ XN_UNLOCK(sc);
error = ether_ioctl(ifp, cmd, data);
- XN_UNLOCK(sc);
+ }
break;
case SIOCSIFMTU:
/* XXX can we alter the MTU on a VN ?*/
More information about the svn-src-all
mailing list