drivers/net/ethernet/mellanox/mlx5/core/en/monitor_stats.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/en/monitor_stats.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/mellanox/mlx5/core/en/monitor_stats.c- Extension
.c- Size
- 5466 bytes
- Lines
- 170
- Domain
- Driver Families
- Bucket
- drivers/net
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
en.hmonitor_stats.hlib/eq.h
Detected Declarations
function mlx5e_monitor_counter_capfunction mlx5e_monitor_counter_supportedfunction mlx5e_monitor_counter_armfunction mlx5e_monitor_counters_workfunction mlx5e_monitor_event_handlerfunction fill_monitor_counter_ppcnt_set1function fill_monitor_counter_q_counter_set1function mlx5e_set_monitor_counterfunction mlx5e_monitor_counter_initfunction mlx5e_monitor_counter_cleanupfunction mlx5_sd_for_each_dev
Annotated Snippet
#include "en.h"
#include "monitor_stats.h"
#include "lib/eq.h"
/* Driver will set the following watch counters list:
* Ppcnt.802_3:
* a_in_range_length_errors Type: 0x0, Counter: 0x0, group_id = N/A
* a_out_of_range_length_field Type: 0x0, Counter: 0x1, group_id = N/A
* a_frame_too_long_errors Type: 0x0, Counter: 0x2, group_id = N/A
* a_frame_check_sequence_errors Type: 0x0, Counter: 0x3, group_id = N/A
* a_alignment_errors Type: 0x0, Counter: 0x4, group_id = N/A
* if_out_discards Type: 0x0, Counter: 0x5, group_id = N/A
* Q_Counters:
* Q[index].rx_out_of_buffer Type: 0x1, Counter: 0x4, group_id = counter_ix
*/
#define NUM_REQ_PPCNT_COUNTER_S1 MLX5_CMD_SET_MONITOR_NUM_PPCNT_COUNTER_SET1
#define NUM_REQ_Q_COUNTERS_S1 MLX5_CMD_SET_MONITOR_NUM_Q_COUNTERS_SET1
static int mlx5e_monitor_counter_cap(struct mlx5_core_dev *mdev)
{
if (!MLX5_CAP_GEN(mdev, max_num_of_monitor_counters))
return false;
if (MLX5_CAP_PCAM_REG(mdev, ppcnt) &&
MLX5_CAP_GEN(mdev, num_ppcnt_monitor_counters) <
NUM_REQ_PPCNT_COUNTER_S1)
return false;
if (MLX5_CAP_GEN(mdev, num_q_monitor_counters) <
NUM_REQ_Q_COUNTERS_S1)
return false;
return true;
}
int mlx5e_monitor_counter_supported(struct mlx5e_priv *priv)
{
struct mlx5_core_dev *pos;
int i;
mlx5_sd_for_each_dev(i, priv->mdev, pos)
if (!mlx5e_monitor_counter_cap(pos))
return false;
return true;
}
static void mlx5e_monitor_counter_arm(struct mlx5_core_dev *mdev)
{
u32 in[MLX5_ST_SZ_DW(arm_monitor_counter_in)] = {};
MLX5_SET(arm_monitor_counter_in, in, opcode,
MLX5_CMD_OP_ARM_MONITOR_COUNTER);
mlx5_cmd_exec_in(mdev, arm_monitor_counter, in);
}
static void mlx5e_monitor_counters_work(struct work_struct *work)
{
struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
monitor_counters_work);
struct mlx5_core_dev *pos;
int i;
mutex_lock(&priv->state_lock);
mlx5e_stats_update_ndo_stats(priv);
mutex_unlock(&priv->state_lock);
mlx5_sd_for_each_dev(i, priv->mdev, pos)
mlx5e_monitor_counter_arm(pos);
}
static int mlx5e_monitor_event_handler(struct notifier_block *nb,
unsigned long event, void *eqe)
{
struct mlx5e_priv *priv = mlx5_nb_cof(nb, struct mlx5e_priv,
monitor_counters_nb);
queue_work(priv->wq, &priv->monitor_counters_work);
return NOTIFY_OK;
}
static int fill_monitor_counter_ppcnt_set1(int cnt, u32 *in)
{
enum mlx5_monitor_counter_ppcnt ppcnt_cnt;
for (ppcnt_cnt = 0;
ppcnt_cnt < NUM_REQ_PPCNT_COUNTER_S1;
ppcnt_cnt++, cnt++) {
MLX5_SET(set_monitor_counter_in, in,
monitor_counter[cnt].type,
MLX5_QUERY_MONITOR_CNT_TYPE_PPCNT);
MLX5_SET(set_monitor_counter_in, in,
monitor_counter[cnt].counter,
ppcnt_cnt);
}
Annotation
- Immediate include surface: `en.h`, `monitor_stats.h`, `lib/eq.h`.
- Detected declarations: `function mlx5e_monitor_counter_cap`, `function mlx5e_monitor_counter_supported`, `function mlx5e_monitor_counter_arm`, `function mlx5e_monitor_counters_work`, `function mlx5e_monitor_event_handler`, `function fill_monitor_counter_ppcnt_set1`, `function fill_monitor_counter_q_counter_set1`, `function mlx5e_set_monitor_counter`, `function mlx5e_monitor_counter_init`, `function mlx5e_monitor_counter_cleanup`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.