Skip to content

Commit cad456d

Browse files
nhormandavem330
authored andcommitted
drop_monitor: convert to modular building
When I first wrote drop monitor I wrote it to just build monolithically. There is no reason it can't be built modularly as well, so lets give it that flexibiity. I've tested this by building it as both a module and monolithically, and it seems to work quite well Change notes: v2) * fixed for_each_present_cpu loops to be more correct as per Eric D. * Converted exit path failures to BUG_ON as per Ben H. v3) * Converted del_timer to del_timer_sync to close race noted by Ben H. Signed-off-by: Neil Horman <nhorman@tuxdriver.com> CC: "David S. Miller" <davem@davemloft.net> CC: Eric Dumazet <eric.dumazet@gmail.com> CC: Ben Hutchings <bhutchings@solarflare.com> Reviewed-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent a1c7fff commit cad456d

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

net/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ config NET_TCPPROBE
296296
module will be called tcp_probe.
297297

298298
config NET_DROP_MONITOR
299-
boolean "Network packet drop alerting service"
299+
tristate "Network packet drop alerting service"
300300
depends on INET && EXPERIMENTAL && TRACEPOINTS
301301
---help---
302302
This feature provides an alerting service to userspace in the

net/core/drop_monitor.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <linux/timer.h>
2525
#include <linux/bitops.h>
2626
#include <linux/slab.h>
27+
#include <linux/module.h>
2728
#include <net/genetlink.h>
2829
#include <net/netevent.h>
2930

@@ -263,9 +264,15 @@ static int set_all_monitor_traces(int state)
263264

264265
switch (state) {
265266
case TRACE_ON:
267+
if (!try_module_get(THIS_MODULE)) {
268+
rc = -ENODEV;
269+
break;
270+
}
271+
266272
rc |= register_trace_kfree_skb(trace_kfree_skb_hit, NULL);
267273
rc |= register_trace_napi_poll(trace_napi_poll_hit, NULL);
268274
break;
275+
269276
case TRACE_OFF:
270277
rc |= unregister_trace_kfree_skb(trace_kfree_skb_hit, NULL);
271278
rc |= unregister_trace_napi_poll(trace_napi_poll_hit, NULL);
@@ -281,6 +288,9 @@ static int set_all_monitor_traces(int state)
281288
kfree_rcu(new_stat, rcu);
282289
}
283290
}
291+
292+
module_put(THIS_MODULE);
293+
284294
break;
285295
default:
286296
rc = 1;
@@ -406,7 +416,7 @@ static int __init init_net_drop_monitor(void)
406416

407417
rc = 0;
408418

409-
for_each_present_cpu(cpu) {
419+
for_each_possible_cpu(cpu) {
410420
data = &per_cpu(dm_cpu_data, cpu);
411421
data->cpu = cpu;
412422
INIT_WORK(&data->dm_alert_work, send_dm_alert);
@@ -425,4 +435,36 @@ static int __init init_net_drop_monitor(void)
425435
return rc;
426436
}
427437

428-
late_initcall(init_net_drop_monitor);
438+
static void exit_net_drop_monitor(void)
439+
{
440+
struct per_cpu_dm_data *data;
441+
int cpu;
442+
443+
BUG_ON(unregister_netdevice_notifier(&dropmon_net_notifier));
444+
445+
/*
446+
* Because of the module_get/put we do in the trace state change path
447+
* we are guarnateed not to have any current users when we get here
448+
* all we need to do is make sure that we don't have any running timers
449+
* or pending schedule calls
450+
*/
451+
452+
for_each_possible_cpu(cpu) {
453+
data = &per_cpu(dm_cpu_data, cpu);
454+
del_timer_sync(&data->send_timer);
455+
cancel_work_sync(&data->dm_alert_work);
456+
/*
457+
* At this point, we should have exclusive access
458+
* to this struct and can free the skb inside it
459+
*/
460+
kfree_skb(data->skb);
461+
}
462+
463+
BUG_ON(genl_unregister_family(&net_drop_monitor_family));
464+
}
465+
466+
module_init(init_net_drop_monitor);
467+
module_exit(exit_net_drop_monitor);
468+
469+
MODULE_LICENSE("GPL v2");
470+
MODULE_AUTHOR("Neil Horman <nhorman@tuxdriver.com>");

0 commit comments

Comments
 (0)