18
18
#include <linux/debugfs.h>
19
19
#include <linux/device.h>
20
20
#include <linux/list.h>
21
+ #include <linux/mutex.h>
21
22
#include <linux/random.h>
22
23
#include <linux/rtnetlink.h>
23
24
#include <net/devlink.h>
@@ -238,6 +239,7 @@ nsim_dev_create(struct nsim_bus_dev *nsim_bus_dev, unsigned int port_count)
238
239
nsim_dev -> switch_id .id_len = sizeof (nsim_dev -> switch_id .id );
239
240
get_random_bytes (nsim_dev -> switch_id .id , nsim_dev -> switch_id .id_len );
240
241
INIT_LIST_HEAD (& nsim_dev -> port_list );
242
+ mutex_init (& nsim_dev -> port_list_lock );
241
243
242
244
nsim_dev -> fib_data = nsim_fib_create ();
243
245
if (IS_ERR (nsim_dev -> fib_data )) {
@@ -285,10 +287,12 @@ void nsim_dev_destroy(struct nsim_dev *nsim_dev)
285
287
devlink_unregister (devlink );
286
288
devlink_resources_unregister (devlink , NULL );
287
289
nsim_fib_destroy (nsim_dev -> fib_data );
290
+ mutex_destroy (& nsim_dev -> port_list_lock );
288
291
devlink_free (devlink );
289
292
}
290
293
291
- static int nsim_dev_port_add (struct nsim_dev * nsim_dev , unsigned int port_index )
294
+ static int __nsim_dev_port_add (struct nsim_dev * nsim_dev ,
295
+ unsigned int port_index )
292
296
{
293
297
struct nsim_dev_port * nsim_dev_port ;
294
298
struct devlink_port * devlink_port ;
@@ -324,7 +328,7 @@ static int nsim_dev_port_add(struct nsim_dev *nsim_dev, unsigned int port_index)
324
328
return err ;
325
329
}
326
330
327
- static void nsim_dev_port_del (struct nsim_dev_port * nsim_dev_port )
331
+ static void __nsim_dev_port_del (struct nsim_dev_port * nsim_dev_port )
328
332
{
329
333
struct devlink_port * devlink_port = & nsim_dev_port -> devlink_port ;
330
334
@@ -340,7 +344,7 @@ static void nsim_dev_port_del_all(struct nsim_dev *nsim_dev)
340
344
341
345
list_for_each_entry_safe (nsim_dev_port , tmp ,
342
346
& nsim_dev -> port_list , list )
343
- nsim_dev_port_del (nsim_dev_port );
347
+ __nsim_dev_port_del (nsim_dev_port );
344
348
}
345
349
346
350
int nsim_dev_probe (struct nsim_bus_dev * nsim_bus_dev )
@@ -355,7 +359,7 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
355
359
dev_set_drvdata (& nsim_bus_dev -> dev , nsim_dev );
356
360
357
361
for (i = 0 ; i < nsim_bus_dev -> port_count ; i ++ ) {
358
- err = nsim_dev_port_add (nsim_dev , i );
362
+ err = __nsim_dev_port_add (nsim_dev , i );
359
363
if (err )
360
364
goto err_port_del_all ;
361
365
}
@@ -375,6 +379,49 @@ void nsim_dev_remove(struct nsim_bus_dev *nsim_bus_dev)
375
379
nsim_dev_destroy (nsim_dev );
376
380
}
377
381
382
+ static struct nsim_dev_port *
383
+ __nsim_dev_port_lookup (struct nsim_dev * nsim_dev , unsigned int port_index )
384
+ {
385
+ struct nsim_dev_port * nsim_dev_port ;
386
+
387
+ list_for_each_entry (nsim_dev_port , & nsim_dev -> port_list , list )
388
+ if (nsim_dev_port -> port_index == port_index )
389
+ return nsim_dev_port ;
390
+ return NULL ;
391
+ }
392
+
393
+ int nsim_dev_port_add (struct nsim_bus_dev * nsim_bus_dev ,
394
+ unsigned int port_index )
395
+ {
396
+ struct nsim_dev * nsim_dev = dev_get_drvdata (& nsim_bus_dev -> dev );
397
+ int err ;
398
+
399
+ mutex_lock (& nsim_dev -> port_list_lock );
400
+ if (__nsim_dev_port_lookup (nsim_dev , port_index ))
401
+ err = - EEXIST ;
402
+ else
403
+ err = __nsim_dev_port_add (nsim_dev , port_index );
404
+ mutex_unlock (& nsim_dev -> port_list_lock );
405
+ return err ;
406
+ }
407
+
408
+ int nsim_dev_port_del (struct nsim_bus_dev * nsim_bus_dev ,
409
+ unsigned int port_index )
410
+ {
411
+ struct nsim_dev * nsim_dev = dev_get_drvdata (& nsim_bus_dev -> dev );
412
+ struct nsim_dev_port * nsim_dev_port ;
413
+ int err = 0 ;
414
+
415
+ mutex_lock (& nsim_dev -> port_list_lock );
416
+ nsim_dev_port = __nsim_dev_port_lookup (nsim_dev , port_index );
417
+ if (!nsim_dev_port )
418
+ err = - ENOENT ;
419
+ else
420
+ __nsim_dev_port_del (nsim_dev_port );
421
+ mutex_unlock (& nsim_dev -> port_list_lock );
422
+ return err ;
423
+ }
424
+
378
425
int nsim_dev_init (void )
379
426
{
380
427
nsim_dev_ddir = debugfs_create_dir (DRV_NAME , NULL );
0 commit comments