Commit 70c69274 authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

drop_monitor: Initialize timer and work item upon tracing enable

The timer and work item are currently initialized once during module
init, but subsequent patches will need to associate different functions
with the work item, based on the configured alert mode.

Allow subsequent patches to make that change by initializing and
de-initializing these objects during tracing enable and disable.

This also guarantees that once the request to disable tracing returns,
no more netlink notifications will be generated.
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7c747838
...@@ -243,13 +243,20 @@ static void trace_napi_poll_hit(void *ignore, struct napi_struct *napi, ...@@ -243,13 +243,20 @@ static void trace_napi_poll_hit(void *ignore, struct napi_struct *napi,
static int net_dm_trace_on_set(struct netlink_ext_ack *extack) static int net_dm_trace_on_set(struct netlink_ext_ack *extack)
{ {
int rc; int cpu, rc;
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;
} }
for_each_possible_cpu(cpu) {
struct per_cpu_dm_data *data = &per_cpu(dm_cpu_data, cpu);
INIT_WORK(&data->dm_alert_work, send_dm_alert);
timer_setup(&data->send_timer, sched_send_work, 0);
}
rc = register_trace_kfree_skb(trace_kfree_skb_hit, NULL); rc = register_trace_kfree_skb(trace_kfree_skb_hit, 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");
...@@ -274,12 +281,23 @@ static int net_dm_trace_on_set(struct netlink_ext_ack *extack) ...@@ -274,12 +281,23 @@ 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;
int cpu;
unregister_trace_napi_poll(trace_napi_poll_hit, NULL); unregister_trace_napi_poll(trace_napi_poll_hit, NULL);
unregister_trace_kfree_skb(trace_kfree_skb_hit, NULL); unregister_trace_kfree_skb(trace_kfree_skb_hit, NULL);
tracepoint_synchronize_unregister(); tracepoint_synchronize_unregister();
/* Make sure we do not send notifications to user space after request
* to stop tracing returns.
*/
for_each_possible_cpu(cpu) {
struct per_cpu_dm_data *data = &per_cpu(dm_cpu_data, cpu);
del_timer_sync(&data->send_timer);
cancel_work_sync(&data->dm_alert_work);
}
list_for_each_entry_safe(new_stat, temp, &hw_stats_list, list) { list_for_each_entry_safe(new_stat, temp, &hw_stats_list, list) {
if (new_stat->dev == NULL) { if (new_stat->dev == NULL) {
list_del_rcu(&new_stat->list); list_del_rcu(&new_stat->list);
...@@ -481,14 +499,10 @@ static void exit_net_drop_monitor(void) ...@@ -481,14 +499,10 @@ static void exit_net_drop_monitor(void)
/* /*
* Because of the module_get/put we do in the trace state change path * Because of the module_get/put we do in the trace state change path
* we are guarnateed not to have any current users when we get here * we are guarnateed not to have any current users when we get here
* all we need to do is make sure that we don't have any running timers
* or pending schedule calls
*/ */
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
data = &per_cpu(dm_cpu_data, cpu); data = &per_cpu(dm_cpu_data, cpu);
del_timer_sync(&data->send_timer);
cancel_work_sync(&data->dm_alert_work);
/* /*
* At this point, we should have exclusive access * At this point, we should have exclusive access
* to this struct and can free the skb inside it * to this struct and can free the skb inside it
......
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