Commit 28315f79 authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

drop_monitor: Add alert mode operations

The next patch is going to add another alert mode in which the dropped
packet is notified to user space, instead of only a summary of recent
drops.

Abstract the differences between the modes by adding alert mode
operations. The operations are selected based on the currently
configured mode and associated with the probes and the work item just
before tracing starts.
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c5ab9b1c
...@@ -62,4 +62,13 @@ enum { ...@@ -62,4 +62,13 @@ enum {
* Our group identifiers * Our group identifiers
*/ */
#define NET_DM_GRP_ALERT 1 #define NET_DM_GRP_ALERT 1
/**
* enum net_dm_alert_mode - Alert mode.
* @NET_DM_ALERT_MODE_SUMMARY: A summary of recent drops is sent to user space.
*/
enum net_dm_alert_mode {
NET_DM_ALERT_MODE_SUMMARY,
};
#endif #endif
...@@ -75,6 +75,16 @@ static int dm_delay = 1; ...@@ -75,6 +75,16 @@ static int dm_delay = 1;
static unsigned long dm_hw_check_delta = 2*HZ; static unsigned long dm_hw_check_delta = 2*HZ;
static LIST_HEAD(hw_stats_list); static LIST_HEAD(hw_stats_list);
static enum net_dm_alert_mode net_dm_alert_mode = NET_DM_ALERT_MODE_SUMMARY;
struct net_dm_alert_ops {
void (*kfree_skb_probe)(void *ignore, struct sk_buff *skb,
void *location);
void (*napi_poll_probe)(void *ignore, struct napi_struct *napi,
int work, int budget);
void (*work_item_func)(struct work_struct *work);
};
static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data) static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data)
{ {
size_t al; size_t al;
...@@ -241,10 +251,23 @@ static void trace_napi_poll_hit(void *ignore, struct napi_struct *napi, ...@@ -241,10 +251,23 @@ static void trace_napi_poll_hit(void *ignore, struct napi_struct *napi,
rcu_read_unlock(); rcu_read_unlock();
} }
static const struct net_dm_alert_ops net_dm_alert_summary_ops = {
.kfree_skb_probe = trace_kfree_skb_hit,
.napi_poll_probe = trace_napi_poll_hit,
.work_item_func = send_dm_alert,
};
static const struct net_dm_alert_ops *net_dm_alert_ops_arr[] = {
[NET_DM_ALERT_MODE_SUMMARY] = &net_dm_alert_summary_ops,
};
static int net_dm_trace_on_set(struct netlink_ext_ack *extack) static int net_dm_trace_on_set(struct netlink_ext_ack *extack)
{ {
const struct net_dm_alert_ops *ops;
int cpu, rc; int cpu, rc;
ops = net_dm_alert_ops_arr[net_dm_alert_mode];
if (!try_module_get(THIS_MODULE)) { if (!try_module_get(THIS_MODULE)) {
NL_SET_ERR_MSG_MOD(extack, "Failed to take reference on module"); NL_SET_ERR_MSG_MOD(extack, "Failed to take reference on module");
return -ENODEV; return -ENODEV;
...@@ -254,7 +277,7 @@ static int net_dm_trace_on_set(struct netlink_ext_ack *extack) ...@@ -254,7 +277,7 @@ static int net_dm_trace_on_set(struct netlink_ext_ack *extack)
struct per_cpu_dm_data *data = &per_cpu(dm_cpu_data, cpu); struct per_cpu_dm_data *data = &per_cpu(dm_cpu_data, cpu);
struct sk_buff *skb; struct sk_buff *skb;
INIT_WORK(&data->dm_alert_work, send_dm_alert); INIT_WORK(&data->dm_alert_work, ops->work_item_func);
timer_setup(&data->send_timer, sched_send_work, 0); timer_setup(&data->send_timer, sched_send_work, 0);
/* Allocate a new per-CPU skb for the summary alert message and /* Allocate a new per-CPU skb for the summary alert message and
* free the old one which might contain stale data from * free the old one which might contain stale data from
...@@ -264,13 +287,13 @@ static int net_dm_trace_on_set(struct netlink_ext_ack *extack) ...@@ -264,13 +287,13 @@ static int net_dm_trace_on_set(struct netlink_ext_ack *extack)
consume_skb(skb); consume_skb(skb);
} }
rc = register_trace_kfree_skb(trace_kfree_skb_hit, NULL); rc = register_trace_kfree_skb(ops->kfree_skb_probe, NULL);
if (rc) { if (rc) {
NL_SET_ERR_MSG_MOD(extack, "Failed to connect probe to kfree_skb() tracepoint"); NL_SET_ERR_MSG_MOD(extack, "Failed to connect probe to kfree_skb() tracepoint");
goto err_module_put; goto err_module_put;
} }
rc = register_trace_napi_poll(trace_napi_poll_hit, NULL); rc = register_trace_napi_poll(ops->napi_poll_probe, NULL);
if (rc) { if (rc) {
NL_SET_ERR_MSG_MOD(extack, "Failed to connect probe to napi_poll() tracepoint"); NL_SET_ERR_MSG_MOD(extack, "Failed to connect probe to napi_poll() tracepoint");
goto err_unregister_trace; goto err_unregister_trace;
...@@ -279,7 +302,7 @@ static int net_dm_trace_on_set(struct netlink_ext_ack *extack) ...@@ -279,7 +302,7 @@ static int net_dm_trace_on_set(struct netlink_ext_ack *extack)
return 0; return 0;
err_unregister_trace: err_unregister_trace:
unregister_trace_kfree_skb(trace_kfree_skb_hit, NULL); unregister_trace_kfree_skb(ops->kfree_skb_probe, NULL);
err_module_put: err_module_put:
module_put(THIS_MODULE); module_put(THIS_MODULE);
return rc; return rc;
...@@ -288,10 +311,13 @@ static int net_dm_trace_on_set(struct netlink_ext_ack *extack) ...@@ -288,10 +311,13 @@ static int net_dm_trace_on_set(struct netlink_ext_ack *extack)
static void net_dm_trace_off_set(void) static void net_dm_trace_off_set(void)
{ {
struct dm_hw_stat_delta *new_stat, *temp; struct dm_hw_stat_delta *new_stat, *temp;
const struct net_dm_alert_ops *ops;
int cpu; int cpu;
unregister_trace_napi_poll(trace_napi_poll_hit, NULL); ops = net_dm_alert_ops_arr[net_dm_alert_mode];
unregister_trace_kfree_skb(trace_kfree_skb_hit, NULL);
unregister_trace_napi_poll(ops->napi_poll_probe, NULL);
unregister_trace_kfree_skb(ops->kfree_skb_probe, NULL);
tracepoint_synchronize_unregister(); tracepoint_synchronize_unregister();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment