@@ -1797,7 +1797,8 @@ static size_t efx_ef10_update_stats_comm
}
static size_t efx_ef10_update_stats_pf(struct efx_nic *efx, u64 *full_stats,
- struct rtnl_link_stats64 *core_stats)
+ struct rtnl_link_stats64 *core_stats,
+ bool can_sleep)
{
struct efx_ef10_nic_data *nic_data = efx->nic_data;
DECLARE_BITMAP(mask, EF10_STAT_COUNT);
@@ -1836,7 +1837,7 @@ static size_t efx_ef10_update_stats_pf(s
return efx_ef10_update_stats_common(efx, full_stats, core_stats);
}
-static int efx_ef10_try_update_nic_stats_vf(struct efx_nic *efx)
+static int efx_ef10_try_update_nic_stats_vf(struct efx_nic *efx, bool can_sleep)
__must_hold(&efx->stats_lock)
{
MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN);
@@ -1849,20 +1850,18 @@ static int efx_ef10_try_update_nic_stats
__le64 *dma_stats;
int rc;
- spin_unlock_bh(&efx->stats_lock);
-
- if (in_interrupt()) {
+ if (!can_sleep) {
/* If in atomic context, cannot update stats. Just update the
* software stats and return so the caller can continue.
*/
- spin_lock_bh(&efx->stats_lock);
efx_update_sw_stats(efx, stats);
return 0;
}
+ spin_unlock_bh(&efx->stats_lock);
efx_ef10_get_stat_mask(efx, mask);
- rc = efx_nic_alloc_buffer(efx, &stats_buf, dma_len, GFP_ATOMIC);
+ rc = efx_nic_alloc_buffer(efx, &stats_buf, dma_len, GFP_KERNEL);
if (rc) {
spin_lock_bh(&efx->stats_lock);
return rc;
@@ -1910,9 +1909,10 @@ static int efx_ef10_try_update_nic_stats
}
static size_t efx_ef10_update_stats_vf(struct efx_nic *efx, u64 *full_stats,
- struct rtnl_link_stats64 *core_stats)
+ struct rtnl_link_stats64 *core_stats,
+ bool can_sleep)
{
- if (efx_ef10_try_update_nic_stats_vf(efx))
+ if (efx_ef10_try_update_nic_stats_vf(efx, can_sleep))
return 0;
return efx_ef10_update_stats_common(efx, full_stats, core_stats);
@@ -599,7 +599,8 @@ static size_t ef100_update_stats_common(
static size_t ef100_update_stats(struct efx_nic *efx,
u64 *full_stats,
- struct rtnl_link_stats64 *core_stats)
+ struct rtnl_link_stats64 *core_stats,
+ bool can_sleep)
{
__le64 *mc_stats = kmalloc(array_size(efx->num_mac_stats, sizeof(__le64)), GFP_ATOMIC);
struct ef100_nic_data *nic_data = efx->nic_data;
@@ -552,7 +552,7 @@ void efx_start_all(struct efx_nic *efx)
efx->type->start_stats(efx);
efx->type->pull_stats(efx);
spin_lock_bh(&efx->stats_lock);
- efx->type->update_stats(efx, NULL, NULL);
+ efx->type->update_stats(efx, NULL, NULL, true);
spin_unlock_bh(&efx->stats_lock);
}
}
@@ -576,7 +576,7 @@ void efx_stop_all(struct efx_nic *efx)
*/
efx->type->pull_stats(efx);
spin_lock_bh(&efx->stats_lock);
- efx->type->update_stats(efx, NULL, NULL);
+ efx->type->update_stats(efx, NULL, NULL, true);
spin_unlock_bh(&efx->stats_lock);
efx->type->stop_stats(efx);
}
@@ -600,7 +600,7 @@ void efx_net_stats(struct net_device *ne
struct efx_nic *efx = netdev_priv(net_dev);
spin_lock_bh(&efx->stats_lock);
- efx->type->update_stats(efx, NULL, stats);
+ efx->type->update_stats(efx, NULL, stats, false);
spin_unlock_bh(&efx->stats_lock);
}
@@ -502,7 +502,7 @@ void efx_ethtool_get_stats(struct net_de
spin_lock_bh(&efx->stats_lock);
/* Get NIC statistics */
- data += efx->type->update_stats(efx, data, NULL);
+ data += efx->type->update_stats(efx, data, NULL, true);
/* Get software statistics */
for (i = 0; i < EFX_ETHTOOL_SW_STAT_COUNT; i++) {
@@ -1358,7 +1358,8 @@ struct efx_nic_type {
void (*finish_flr)(struct efx_nic *efx);
size_t (*describe_stats)(struct efx_nic *efx, u8 *names);
size_t (*update_stats)(struct efx_nic *efx, u64 *full_stats,
- struct rtnl_link_stats64 *core_stats);
+ struct rtnl_link_stats64 *core_stats,
+ bool can_sleep);
void (*start_stats)(struct efx_nic *efx);
void (*pull_stats)(struct efx_nic *efx);
void (*stop_stats)(struct efx_nic *efx);
@@ -587,7 +587,8 @@ static int siena_try_update_nic_stats(st
}
static size_t siena_update_nic_stats(struct efx_nic *efx, u64 *full_stats,
- struct rtnl_link_stats64 *core_stats)
+ struct rtnl_link_stats64 *core_stats,
+ bool can_sleep)
{
struct siena_nic_data *nic_data = efx->nic_data;
u64 *stats = nic_data->stats;