@@ -357,25 +357,52 @@ static void **alloc_pg_vec(struct netlink_sock *nlk,
357
357
return NULL ;
358
358
}
359
359
360
+
361
+ static void
362
+ __netlink_set_ring (struct sock * sk , struct nl_mmap_req * req , bool tx_ring , void * * pg_vec ,
363
+ unsigned int order )
364
+ {
365
+ struct netlink_sock * nlk = nlk_sk (sk );
366
+ struct sk_buff_head * queue ;
367
+ struct netlink_ring * ring ;
368
+
369
+ queue = tx_ring ? & sk -> sk_write_queue : & sk -> sk_receive_queue ;
370
+ ring = tx_ring ? & nlk -> tx_ring : & nlk -> rx_ring ;
371
+
372
+ spin_lock_bh (& queue -> lock );
373
+
374
+ ring -> frame_max = req -> nm_frame_nr - 1 ;
375
+ ring -> head = 0 ;
376
+ ring -> frame_size = req -> nm_frame_size ;
377
+ ring -> pg_vec_pages = req -> nm_block_size / PAGE_SIZE ;
378
+
379
+ swap (ring -> pg_vec_len , req -> nm_block_nr );
380
+ swap (ring -> pg_vec_order , order );
381
+ swap (ring -> pg_vec , pg_vec );
382
+
383
+ __skb_queue_purge (queue );
384
+ spin_unlock_bh (& queue -> lock );
385
+
386
+ WARN_ON (atomic_read (& nlk -> mapped ));
387
+
388
+ if (pg_vec )
389
+ free_pg_vec (pg_vec , order , req -> nm_block_nr );
390
+ }
391
+
360
392
static int netlink_set_ring (struct sock * sk , struct nl_mmap_req * req ,
361
- bool closing , bool tx_ring )
393
+ bool tx_ring )
362
394
{
363
395
struct netlink_sock * nlk = nlk_sk (sk );
364
396
struct netlink_ring * ring ;
365
- struct sk_buff_head * queue ;
366
397
void * * pg_vec = NULL ;
367
398
unsigned int order = 0 ;
368
- int err ;
369
399
370
400
ring = tx_ring ? & nlk -> tx_ring : & nlk -> rx_ring ;
371
- queue = tx_ring ? & sk -> sk_write_queue : & sk -> sk_receive_queue ;
372
401
373
- if (!closing ) {
374
- if (atomic_read (& nlk -> mapped ))
375
- return - EBUSY ;
376
- if (atomic_read (& ring -> pending ))
377
- return - EBUSY ;
378
- }
402
+ if (atomic_read (& nlk -> mapped ))
403
+ return - EBUSY ;
404
+ if (atomic_read (& ring -> pending ))
405
+ return - EBUSY ;
379
406
380
407
if (req -> nm_block_nr ) {
381
408
if (ring -> pg_vec != NULL )
@@ -407,31 +434,19 @@ static int netlink_set_ring(struct sock *sk, struct nl_mmap_req *req,
407
434
return - EINVAL ;
408
435
}
409
436
410
- err = - EBUSY ;
411
437
mutex_lock (& nlk -> pg_vec_lock );
412
- if (closing || atomic_read (& nlk -> mapped ) == 0 ) {
413
- err = 0 ;
414
- spin_lock_bh (& queue -> lock );
415
-
416
- ring -> frame_max = req -> nm_frame_nr - 1 ;
417
- ring -> head = 0 ;
418
- ring -> frame_size = req -> nm_frame_size ;
419
- ring -> pg_vec_pages = req -> nm_block_size / PAGE_SIZE ;
420
-
421
- swap (ring -> pg_vec_len , req -> nm_block_nr );
422
- swap (ring -> pg_vec_order , order );
423
- swap (ring -> pg_vec , pg_vec );
424
-
425
- __skb_queue_purge (queue );
426
- spin_unlock_bh (& queue -> lock );
427
-
428
- WARN_ON (atomic_read (& nlk -> mapped ));
438
+ if (atomic_read (& nlk -> mapped ) == 0 ) {
439
+ __netlink_set_ring (sk , req , tx_ring , pg_vec , order );
440
+ mutex_unlock (& nlk -> pg_vec_lock );
441
+ return 0 ;
429
442
}
443
+
430
444
mutex_unlock (& nlk -> pg_vec_lock );
431
445
432
446
if (pg_vec )
433
447
free_pg_vec (pg_vec , order , req -> nm_block_nr );
434
- return err ;
448
+
449
+ return - EBUSY ;
435
450
}
436
451
437
452
static void netlink_mm_open (struct vm_area_struct * vma )
@@ -900,10 +915,10 @@ static void netlink_sock_destruct(struct sock *sk)
900
915
901
916
memset (& req , 0 , sizeof (req ));
902
917
if (nlk -> rx_ring .pg_vec )
903
- netlink_set_ring (sk , & req , true, false );
918
+ __netlink_set_ring (sk , & req , false, NULL , 0 );
904
919
memset (& req , 0 , sizeof (req ));
905
920
if (nlk -> tx_ring .pg_vec )
906
- netlink_set_ring (sk , & req , true, true );
921
+ __netlink_set_ring (sk , & req , true, NULL , 0 );
907
922
}
908
923
#endif /* CONFIG_NETLINK_MMAP */
909
924
@@ -2223,7 +2238,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
2223
2238
return - EINVAL ;
2224
2239
if (copy_from_user (& req , optval , sizeof (req )))
2225
2240
return - EFAULT ;
2226
- err = netlink_set_ring (sk , & req , false,
2241
+ err = netlink_set_ring (sk , & req ,
2227
2242
optname == NETLINK_TX_RING );
2228
2243
break ;
2229
2244
}
0 commit comments