Get network stats from accelerator plugin diff -r 709db80c03c3 drivers/xen/netfront/accel.c --- a/drivers/xen/netfront/accel.c Mon Oct 22 14:29:07 2007 +0100 +++ b/drivers/xen/netfront/accel.c Mon Oct 29 16:48:27 2007 +0000 @@ -529,6 +529,7 @@ static void accelerator_remove_hooks(str static void accelerator_remove_hooks(struct netfront_accelerator *accelerator, int remove_master) { + struct netfront_accel_hooks *hooks; struct netfront_accel_vif_state *vif_state, *tmp; unsigned flags; @@ -537,6 +538,7 @@ static void accelerator_remove_hooks(str list_for_each_entry_safe(vif_state, tmp, &accelerator->vif_states, link) { + hooks = vif_state->hooks; accelerator_remove_single_hook(accelerator, vif_state); /* @@ -544,7 +546,12 @@ static void accelerator_remove_hooks(str * were set, must be called without lock held */ spin_unlock_irqrestore(&accelerator->vif_states_lock, flags); + + /* Last chance to get statistics from the accelerator */ + hooks->get_stats(vif_state->np->netdev, &vif_state->np->stats); + kref_put(&vif_state->vif_kref, vif_kref_release); + spin_lock_irqsave(&accelerator->vif_states_lock, flags); } @@ -663,7 +670,8 @@ int netfront_accelerator_call_remove(str kref_get(&np->accel_vif_state.vif_kref); spin_unlock_irqrestore (&np->accelerator->vif_states_lock, flags); - + /* Last chance to get statistics from the accelerator */ + vif_state->hooks->get_stats(np->netdev, &np->stats); rc = np->accel_vif_state.hooks->remove(dev); kref_put(&np->accel_vif_state.vif_kref, @@ -720,6 +728,9 @@ int netfront_accelerator_call_suspend(st spin_unlock_irqrestore (&np->accelerator->vif_states_lock, flags); + /* Last chance to get stats from the accelerator */ + np->accel_vif_state.hooks->get_stats(dev, &np->stats); + rc = np->accel_vif_state.hooks->suspend(dev); kref_put(&np->accel_vif_state.vif_kref, @@ -869,6 +880,42 @@ void netfront_accelerator_call_stop_napi (&np->accelerator->vif_states_lock, flags); } } +} + + +int netfront_accelerator_call_get_stats(struct netfront_info *np, + struct net_device *dev) +{ + struct netfront_accel_hooks *hooks; + unsigned flags; + int rc = 0; + + /* + * Call the get_stats accelerator hook. The use count for the + * accelerator's hooks is incremented for the duration of the + * call to prevent the accelerator being able to modify the + * hooks in the middle (by, for example, unloading) + */ + + if (np->accel_vif_state.hooks) { + spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); + hooks = np->accel_vif_state.hooks; + if (hooks) { + kref_get(&np->accel_vif_state.vif_kref); + spin_unlock_irqrestore + (&np->accelerator->vif_states_lock, flags); + + rc = np->accel_vif_state.hooks->get_stats(dev, + &np->stats); + + kref_put(&np->accel_vif_state.vif_kref, + vif_kref_release); + } else { + spin_unlock_irqrestore + (&np->accelerator->vif_states_lock, flags); + } + } + return rc; } diff -r 709db80c03c3 drivers/xen/netfront/netfront.c --- a/drivers/xen/netfront/netfront.c Mon Oct 22 14:29:07 2007 +0100 +++ b/drivers/xen/netfront/netfront.c Mon Oct 29 16:28:47 2007 +0000 @@ -1674,6 +1674,8 @@ static struct net_device_stats *network_ static struct net_device_stats *network_get_stats(struct net_device *dev) { struct netfront_info *np = netdev_priv(dev); + + netfront_accelerator_call_get_stats(np, dev); return &np->stats; } diff -r 709db80c03c3 drivers/xen/netfront/netfront.h --- a/drivers/xen/netfront/netfront.h Mon Oct 22 14:29:07 2007 +0100 +++ b/drivers/xen/netfront/netfront.h Mon Oct 29 16:28:47 2007 +0000 @@ -96,12 +96,17 @@ struct netfront_accel_hooks { * path has slots too */ int (*check_busy)(struct net_device *dev); + /* + * Get the fastpath network statistics + */ + int (*get_stats)(struct net_device *dev, + struct net_device_stats *stats); }; /* Version of API/protocol for communication between netfront and acceleration plugin supported */ -#define NETFRONT_ACCEL_VERSION 0x00010000 +#define NETFRONT_ACCEL_VERSION 0x00010001 /* * Per-netfront device state for the accelerator. This is used to @@ -295,7 +300,9 @@ extern extern void netfront_accelerator_call_stop_napi_irq(struct netfront_info *np, struct net_device *dev); - +extern +int netfront_accelerator_call_get_stats(struct netfront_info *np, + struct net_device *dev); extern int netfront_load_accelerator(struct netfront_info *np, struct xenbus_device *dev,