Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sfc: DMA the VF stats only when requested

Firmware does not support a periodic DMA of vadaptor-stats
on VFs, so only update the stats buffer when stats are
requested (when running "ethtool -S" or an ip/ifconfig
command that reports stats).

Signed-off-by: Shradha Shah <sshah@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Daniel Pieczko and committed by
David S. Miller
d7788196 3c36a2ad

+112 -41
+109 -40
drivers/net/ethernet/sfc/ef10.c
··· 1190 1190 mask, names); 1191 1191 } 1192 1192 1193 - static int efx_ef10_try_update_nic_stats(struct efx_nic *efx) 1193 + static size_t efx_ef10_update_stats_common(struct efx_nic *efx, u64 *full_stats, 1194 + struct rtnl_link_stats64 *core_stats) 1195 + { 1196 + DECLARE_BITMAP(mask, EF10_STAT_COUNT); 1197 + struct efx_ef10_nic_data *nic_data = efx->nic_data; 1198 + u64 *stats = nic_data->stats; 1199 + size_t stats_count = 0, index; 1200 + 1201 + efx_ef10_get_stat_mask(efx, mask); 1202 + 1203 + if (full_stats) { 1204 + for_each_set_bit(index, mask, EF10_STAT_COUNT) { 1205 + if (efx_ef10_stat_desc[index].name) { 1206 + *full_stats++ = stats[index]; 1207 + ++stats_count; 1208 + } 1209 + } 1210 + } 1211 + 1212 + if (core_stats) { 1213 + core_stats->rx_packets = stats[EF10_STAT_port_rx_packets]; 1214 + core_stats->tx_packets = stats[EF10_STAT_port_tx_packets]; 1215 + core_stats->rx_bytes = stats[EF10_STAT_port_rx_bytes]; 1216 + core_stats->tx_bytes = stats[EF10_STAT_port_tx_bytes]; 1217 + core_stats->rx_dropped = stats[EF10_STAT_port_rx_nodesc_drops] + 1218 + stats[GENERIC_STAT_rx_nodesc_trunc] + 1219 + stats[GENERIC_STAT_rx_noskb_drops]; 1220 + core_stats->multicast = stats[EF10_STAT_port_rx_multicast]; 1221 + core_stats->rx_length_errors = 1222 + stats[EF10_STAT_port_rx_gtjumbo] + 1223 + stats[EF10_STAT_port_rx_length_error]; 1224 + core_stats->rx_crc_errors = stats[EF10_STAT_port_rx_bad]; 1225 + core_stats->rx_frame_errors = 1226 + stats[EF10_STAT_port_rx_align_error]; 1227 + core_stats->rx_fifo_errors = stats[EF10_STAT_port_rx_overflow]; 1228 + core_stats->rx_errors = (core_stats->rx_length_errors + 1229 + core_stats->rx_crc_errors + 1230 + core_stats->rx_frame_errors); 1231 + } 1232 + 1233 + return stats_count; 1234 + } 1235 + 1236 + static int efx_ef10_try_update_nic_stats_pf(struct efx_nic *efx) 1194 1237 { 1195 1238 struct efx_ef10_nic_data *nic_data = efx->nic_data; 1196 1239 DECLARE_BITMAP(mask, EF10_STAT_COUNT); ··· 1270 1227 } 1271 1228 1272 1229 1273 - static size_t efx_ef10_update_stats(struct efx_nic *efx, u64 *full_stats, 1274 - struct rtnl_link_stats64 *core_stats) 1230 + static size_t efx_ef10_update_stats_pf(struct efx_nic *efx, u64 *full_stats, 1231 + struct rtnl_link_stats64 *core_stats) 1275 1232 { 1276 - DECLARE_BITMAP(mask, EF10_STAT_COUNT); 1277 - struct efx_ef10_nic_data *nic_data = efx->nic_data; 1278 - u64 *stats = nic_data->stats; 1279 - size_t stats_count = 0, index; 1280 1233 int retry; 1281 - 1282 - efx_ef10_get_stat_mask(efx, mask); 1283 1234 1284 1235 /* If we're unlucky enough to read statistics during the DMA, wait 1285 1236 * up to 10ms for it to finish (typically takes <500us) 1286 1237 */ 1287 1238 for (retry = 0; retry < 100; ++retry) { 1288 - if (efx_ef10_try_update_nic_stats(efx) == 0) 1239 + if (efx_ef10_try_update_nic_stats_pf(efx) == 0) 1289 1240 break; 1290 1241 udelay(100); 1291 1242 } 1292 1243 1293 - if (full_stats) { 1294 - for_each_set_bit(index, mask, EF10_STAT_COUNT) { 1295 - if (efx_ef10_stat_desc[index].name) { 1296 - *full_stats++ = stats[index]; 1297 - ++stats_count; 1298 - } 1299 - } 1244 + return efx_ef10_update_stats_common(efx, full_stats, core_stats); 1245 + } 1246 + 1247 + static int efx_ef10_try_update_nic_stats_vf(struct efx_nic *efx) 1248 + { 1249 + MCDI_DECLARE_BUF(inbuf, MC_CMD_MAC_STATS_IN_LEN); 1250 + struct efx_ef10_nic_data *nic_data = efx->nic_data; 1251 + DECLARE_BITMAP(mask, EF10_STAT_COUNT); 1252 + __le64 generation_start, generation_end; 1253 + u64 *stats = nic_data->stats; 1254 + u32 dma_len = MC_CMD_MAC_NSTATS * sizeof(u64); 1255 + struct efx_buffer stats_buf; 1256 + __le64 *dma_stats; 1257 + int rc; 1258 + 1259 + efx_ef10_get_stat_mask(efx, mask); 1260 + 1261 + rc = efx_nic_alloc_buffer(efx, &stats_buf, dma_len, GFP_ATOMIC); 1262 + if (rc) 1263 + return rc; 1264 + 1265 + dma_stats = stats_buf.addr; 1266 + dma_stats[MC_CMD_MAC_GENERATION_END] = EFX_MC_STATS_GENERATION_INVALID; 1267 + 1268 + MCDI_SET_QWORD(inbuf, MAC_STATS_IN_DMA_ADDR, stats_buf.dma_addr); 1269 + MCDI_POPULATE_DWORD_1(inbuf, MAC_STATS_IN_CMD, 1270 + MAC_STATS_IN_DMA, true); 1271 + MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len); 1272 + MCDI_SET_DWORD(inbuf, MAC_STATS_IN_PORT_ID, EVB_PORT_ID_ASSIGNED); 1273 + 1274 + spin_unlock_bh(&efx->stats_lock); 1275 + rc = efx_mcdi_rpc(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf), NULL, 1276 + 0, NULL); 1277 + spin_lock_bh(&efx->stats_lock); 1278 + if (rc) 1279 + goto out; 1280 + 1281 + generation_end = dma_stats[MC_CMD_MAC_GENERATION_END]; 1282 + if (generation_end == EFX_MC_STATS_GENERATION_INVALID) 1283 + goto out; 1284 + rmb(); 1285 + efx_nic_update_stats(efx_ef10_stat_desc, EF10_STAT_COUNT, mask, 1286 + stats, stats_buf.addr, false); 1287 + rmb(); 1288 + generation_start = dma_stats[MC_CMD_MAC_GENERATION_START]; 1289 + if (generation_end != generation_start) { 1290 + rc = -EAGAIN; 1291 + goto out; 1300 1292 } 1301 1293 1302 - if (core_stats) { 1303 - core_stats->rx_packets = stats[EF10_STAT_port_rx_packets]; 1304 - core_stats->tx_packets = stats[EF10_STAT_port_tx_packets]; 1305 - core_stats->rx_bytes = stats[EF10_STAT_port_rx_bytes]; 1306 - core_stats->tx_bytes = stats[EF10_STAT_port_tx_bytes]; 1307 - core_stats->rx_dropped = stats[EF10_STAT_port_rx_nodesc_drops] + 1308 - stats[GENERIC_STAT_rx_nodesc_trunc] + 1309 - stats[GENERIC_STAT_rx_noskb_drops]; 1310 - core_stats->multicast = stats[EF10_STAT_port_rx_multicast]; 1311 - core_stats->rx_length_errors = 1312 - stats[EF10_STAT_port_rx_gtjumbo] + 1313 - stats[EF10_STAT_port_rx_length_error]; 1314 - core_stats->rx_crc_errors = stats[EF10_STAT_port_rx_bad]; 1315 - core_stats->rx_frame_errors = 1316 - stats[EF10_STAT_port_rx_align_error]; 1317 - core_stats->rx_fifo_errors = stats[EF10_STAT_port_rx_overflow]; 1318 - core_stats->rx_errors = (core_stats->rx_length_errors + 1319 - core_stats->rx_crc_errors + 1320 - core_stats->rx_frame_errors); 1321 - } 1294 + efx_update_sw_stats(efx, stats); 1295 + out: 1296 + efx_nic_free_buffer(efx, &stats_buf); 1297 + return rc; 1298 + } 1322 1299 1323 - return stats_count; 1300 + static size_t efx_ef10_update_stats_vf(struct efx_nic *efx, u64 *full_stats, 1301 + struct rtnl_link_stats64 *core_stats) 1302 + { 1303 + if (efx_ef10_try_update_nic_stats_vf(efx)) 1304 + return 0; 1305 + 1306 + return efx_ef10_update_stats_common(efx, full_stats, core_stats); 1324 1307 } 1325 1308 1326 1309 static void efx_ef10_push_irq_moderation(struct efx_channel *channel) ··· 4191 4122 .prepare_flr = efx_ef10_prepare_flr, 4192 4123 .finish_flr = efx_port_dummy_op_void, 4193 4124 .describe_stats = efx_ef10_describe_stats, 4194 - .update_stats = efx_ef10_update_stats, 4125 + .update_stats = efx_ef10_update_stats_vf, 4195 4126 .start_stats = efx_port_dummy_op_void, 4196 4127 .pull_stats = efx_port_dummy_op_void, 4197 4128 .stop_stats = efx_port_dummy_op_void, ··· 4293 4224 .prepare_flr = efx_ef10_prepare_flr, 4294 4225 .finish_flr = efx_port_dummy_op_void, 4295 4226 .describe_stats = efx_ef10_describe_stats, 4296 - .update_stats = efx_ef10_update_stats, 4227 + .update_stats = efx_ef10_update_stats_pf, 4297 4228 .start_stats = efx_mcdi_mac_start_stats, 4298 4229 .pull_stats = efx_mcdi_mac_pull_stats, 4299 4230 .stop_stats = efx_mcdi_mac_stop_stats,
+3 -1
drivers/net/ethernet/sfc/mcdi_pcol.h
··· 2755 2755 #define MC_CMD_0x2e_PRIVILEGE_CTG SRIOV_CTG_GENERAL 2756 2756 2757 2757 /* MC_CMD_MAC_STATS_IN msgrequest */ 2758 - #define MC_CMD_MAC_STATS_IN_LEN 16 2758 + #define MC_CMD_MAC_STATS_IN_LEN 20 2759 2759 /* ??? */ 2760 2760 #define MC_CMD_MAC_STATS_IN_DMA_ADDR_OFST 0 2761 2761 #define MC_CMD_MAC_STATS_IN_DMA_ADDR_LEN 8 ··· 2777 2777 #define MC_CMD_MAC_STATS_IN_PERIOD_MS_LBN 16 2778 2778 #define MC_CMD_MAC_STATS_IN_PERIOD_MS_WIDTH 16 2779 2779 #define MC_CMD_MAC_STATS_IN_DMA_LEN_OFST 12 2780 + /* port id so vadapter stats can be provided */ 2781 + #define MC_CMD_MAC_STATS_IN_PORT_ID_OFST 16 2780 2782 2781 2783 /* MC_CMD_MAC_STATS_OUT_DMA msgresponse */ 2782 2784 #define MC_CMD_MAC_STATS_OUT_DMA_LEN 0