4343 * netlink alerts
4444 */
4545static int trace_state = TRACE_OFF ;
46- static DEFINE_MUTEX (trace_state_mutex );
46+
47+ /* net_dm_mutex
48+ *
49+ * An overall lock guarding every operation coming from userspace.
50+ * It also guards the global 'hw_stats_list' list.
51+ */
52+ static DEFINE_MUTEX (net_dm_mutex );
4753
4854struct per_cpu_dm_data {
49- spinlock_t lock ;
55+ spinlock_t lock ; /* Protects 'skb' and 'send_timer' */
5056 struct sk_buff * skb ;
5157 struct work_struct dm_alert_work ;
5258 struct timer_list send_timer ;
@@ -235,22 +241,21 @@ static void trace_napi_poll_hit(void *ignore, struct napi_struct *napi,
235241 rcu_read_unlock ();
236242}
237243
238- static int set_all_monitor_traces (int state )
244+ static int set_all_monitor_traces (int state , struct netlink_ext_ack * extack )
239245{
240246 int rc = 0 ;
241247 struct dm_hw_stat_delta * new_stat = NULL ;
242248 struct dm_hw_stat_delta * temp ;
243249
244- mutex_lock (& trace_state_mutex );
245-
246250 if (state == trace_state ) {
247- rc = - EAGAIN ;
248- goto out_unlock ;
251+ NL_SET_ERR_MSG_MOD ( extack , "Trace state already set to requested state" ) ;
252+ return - EAGAIN ;
249253 }
250254
251255 switch (state ) {
252256 case TRACE_ON :
253257 if (!try_module_get (THIS_MODULE )) {
258+ NL_SET_ERR_MSG_MOD (extack , "Failed to take reference on module" );
254259 rc = - ENODEV ;
255260 break ;
256261 }
@@ -288,30 +293,28 @@ static int set_all_monitor_traces(int state)
288293 else
289294 rc = - EINPROGRESS ;
290295
291- out_unlock :
292- mutex_unlock (& trace_state_mutex );
293-
294296 return rc ;
295297}
296298
297-
298299static int net_dm_cmd_config (struct sk_buff * skb ,
299300 struct genl_info * info )
300301{
301- return - ENOTSUPP ;
302+ NL_SET_ERR_MSG_MOD (info -> extack , "Command not supported" );
303+
304+ return - EOPNOTSUPP ;
302305}
303306
304307static int net_dm_cmd_trace (struct sk_buff * skb ,
305308 struct genl_info * info )
306309{
307310 switch (info -> genlhdr -> cmd ) {
308311 case NET_DM_CMD_START :
309- return set_all_monitor_traces (TRACE_ON );
312+ return set_all_monitor_traces (TRACE_ON , info -> extack );
310313 case NET_DM_CMD_STOP :
311- return set_all_monitor_traces (TRACE_OFF );
314+ return set_all_monitor_traces (TRACE_OFF , info -> extack );
312315 }
313316
314- return - ENOTSUPP ;
317+ return - EOPNOTSUPP ;
315318}
316319
317320static int dropmon_net_event (struct notifier_block * ev_block ,
@@ -330,12 +333,12 @@ static int dropmon_net_event(struct notifier_block *ev_block,
330333
331334 new_stat -> dev = dev ;
332335 new_stat -> last_rx = jiffies ;
333- mutex_lock (& trace_state_mutex );
336+ mutex_lock (& net_dm_mutex );
334337 list_add_rcu (& new_stat -> list , & hw_stats_list );
335- mutex_unlock (& trace_state_mutex );
338+ mutex_unlock (& net_dm_mutex );
336339 break ;
337340 case NETDEV_UNREGISTER :
338- mutex_lock (& trace_state_mutex );
341+ mutex_lock (& net_dm_mutex );
339342 list_for_each_entry_safe (new_stat , tmp , & hw_stats_list , list ) {
340343 if (new_stat -> dev == dev ) {
341344 new_stat -> dev = NULL ;
@@ -346,7 +349,7 @@ static int dropmon_net_event(struct notifier_block *ev_block,
346349 }
347350 }
348351 }
349- mutex_unlock (& trace_state_mutex );
352+ mutex_unlock (& net_dm_mutex );
350353 break ;
351354 }
352355out :
@@ -371,10 +374,26 @@ static const struct genl_ops dropmon_ops[] = {
371374 },
372375};
373376
377+ static int net_dm_nl_pre_doit (const struct genl_ops * ops ,
378+ struct sk_buff * skb , struct genl_info * info )
379+ {
380+ mutex_lock (& net_dm_mutex );
381+
382+ return 0 ;
383+ }
384+
385+ static void net_dm_nl_post_doit (const struct genl_ops * ops ,
386+ struct sk_buff * skb , struct genl_info * info )
387+ {
388+ mutex_unlock (& net_dm_mutex );
389+ }
390+
374391static struct genl_family net_drop_monitor_family __ro_after_init = {
375392 .hdrsize = 0 ,
376393 .name = "NET_DM" ,
377394 .version = 2 ,
395+ .pre_doit = net_dm_nl_pre_doit ,
396+ .post_doit = net_dm_nl_post_doit ,
378397 .module = THIS_MODULE ,
379398 .ops = dropmon_ops ,
380399 .n_ops = ARRAY_SIZE (dropmon_ops ),
@@ -421,7 +440,6 @@ static int __init init_net_drop_monitor(void)
421440 reset_per_cpu_data (data );
422441 }
423442
424-
425443 goto out ;
426444
427445out_unreg :
0 commit comments