FreeBSD/sys/dev/ixgbe/if_ixv.c
/*********************************************************************
 *  Timer routine
 *
 *  This routine checks for link status,updates statistics,
 *  and runs the watchdog check.
 *
 **********************************************************************/
Timer routine
This routine checks for link status,updates statistics,
and runs the watchdog check.
Timer routine This routine checks for link status updates statistics and runs the watchdog check .
static void
ixv_local_timer(void *arg)
{
	struct adapter	*adapter = arg;
	device_t	dev = adapter->dev;
	struct ix_queue	*que = adapter->queues;
	u64		queues = 0;
	int		hung = 0;
	mtx_assert(&adapter->core_mtx, MA_OWNED);
	ixv_update_link_status(adapter);
	ixv_update_stats(adapter);
	for (int i = 0; i < adapter->num_queues; i++, que++) {
		if (que->txr->busy)
			queues |= ((u64)1 << que->me);
		if (que->busy == IXGBE_QUEUE_HUNG) {
			++hung;
			adapter->active_queues &= ~((u64)1 << que->me);
			continue;
		} else {
			if ((adapter->active_queues & ((u64)1 << que->me)) == 0)
                                adapter->active_queues |= ((u64)1 << que->me);
		}
		if (que->busy >= IXGBE_MAX_TX_BUSY) {
			device_printf(dev,"Warning queue %d "
			    "appears to be hung!\n", i);
			que->txr->busy = IXGBE_QUEUE_HUNG;
			++hung;
		}
	}
	if (hung == adapter->num_queues)
		goto watchdog;
	else if (queues != 0) { 
		ixv_rearm_queues(adapter, queues);
	}
	callout_reset(&adapter->timer, hz, ixv_local_timer, adapter);
	return;
watchdog:
	device_printf(adapter->dev, "Watchdog timeout -- resetting\n");
	adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
	adapter->watchdog_events++;
	ixv_init_locked(adapter);
}
static void ixv_local_timer ( void * arg ) { struct adapter * adapter = arg ; device_t dev = adapter -> dev ; struct ix_queue * que = adapter -> queues ; u64 queues = 0 ; int hung = 0 ; mtx_assert ( & adapter -> core_mtx , MA_OWNED ) ; ixv_update_link_status ( adapter ) ; ixv_update_stats ( adapter ) ; for ( int i = 0 ; i < adapter -> num_queues ; i ++ , que ++ ) { if ( que -> txr -> busy ) queues |= ( ( u64 ) 1 << que -> me ) ; if ( que -> busy == IXGBE_QUEUE_HUNG ) { ++ hung ; adapter -> active_queues &= ~ ( ( u64 ) 1 << que -> me ) ; continue ; } else { if ( ( adapter -> active_queues & ( ( u64 ) 1 << que -> me ) ) == 0 ) adapter -> active_queues |= ( ( u64 ) 1 << que -> me ) ; } if ( que -> busy >= IXGBE_MAX_TX_BUSY ) { device_printf ( dev , " " " \n " , i ) ; que -> txr -> busy = IXGBE_QUEUE_HUNG ; ++ hung ; } } if ( hung == adapter -> num_queues ) goto watchdog ; else if ( queues != 0 ) { ixv_rearm_queues ( adapter , queues ) ; } callout_reset ( & adapter -> timer , hz , ixv_local_timer , adapter ) ; return ; watchdog : device_printf ( adapter -> dev , " \n " ) ; adapter -> ifp -> if_drv_flags &= ~ IFF_DRV_RUNNING ; adapter -> watchdog_events ++ ; ixv_init_locked ( adapter ) ; }
Timer routine
  This routine checks for link status,updates statistics,
  and runs the watchdog check.
Timer routine This routine checks for link status updates statistics and runs the watchdog check .
/* Stats Update */ /*
	** Check the TX queues status
	**      - mark hung queues so we don't schedule on them
	**      - watchdog only if all queues show hung
	*/ /* Keep track of queues with work for soft irq */ /*
		** Each time txeof runs without cleaning, but there
		** are uncleaned descriptors it increments busy. If
		** we get to the MAX we declare it hung.
		*/ /* Mark the queue as inactive */ /* Check if we've come back from hung */ /* Only truly watchdog if all queues show hung */ /* Force an IRQ on queues with work */