@@ -350,25 +350,52 @@ static void **alloc_pg_vec(struct netlink_sock *nlk,
350
350
return NULL ;
351
351
}
352
352
353
+
354
+ static void
355
+ __netlink_set_ring (struct sock * sk , struct nl_mmap_req * req , bool tx_ring , void * * pg_vec ,
356
+ unsigned int order )
357
+ {
358
+ struct netlink_sock * nlk = nlk_sk (sk );
359
+ struct sk_buff_head * queue ;
360
+ struct netlink_ring * ring ;
361
+
362
+ queue = tx_ring ? & sk -> sk_write_queue : & sk -> sk_receive_queue ;
363
+ ring = tx_ring ? & nlk -> tx_ring : & nlk -> rx_ring ;
364
+
365
+ spin_lock_bh (& queue -> lock );
366
+
367
+ ring -> frame_max = req -> nm_frame_nr - 1 ;
368
+ ring -> head = 0 ;
369
+ ring -> frame_size = req -> nm_frame_size ;
370
+ ring -> pg_vec_pages = req -> nm_block_size / PAGE_SIZE ;
371
+
372
+ swap (ring -> pg_vec_len , req -> nm_block_nr );
373
+ swap (ring -> pg_vec_order , order );
374
+ swap (ring -> pg_vec , pg_vec );
375
+
376
+ __skb_queue_purge (queue );
377
+ spin_unlock_bh (& queue -> lock );
378
+
379
+ WARN_ON (atomic_read (& nlk -> mapped ));
380
+
381
+ if (pg_vec )
382
+ free_pg_vec (pg_vec , order , req -> nm_block_nr );
383
+ }
384
+
353
385
static int netlink_set_ring (struct sock * sk , struct nl_mmap_req * req ,
354
- bool closing , bool tx_ring )
386
+ bool tx_ring )
355
387
{
356
388
struct netlink_sock * nlk = nlk_sk (sk );
357
389
struct netlink_ring * ring ;
358
- struct sk_buff_head * queue ;
359
390
void * * pg_vec = NULL ;
360
391
unsigned int order = 0 ;
361
- int err ;
362
392
363
393
ring = tx_ring ? & nlk -> tx_ring : & nlk -> rx_ring ;
364
- queue = tx_ring ? & sk -> sk_write_queue : & sk -> sk_receive_queue ;
365
394
366
- if (!closing ) {
367
- if (atomic_read (& nlk -> mapped ))
368
- return - EBUSY ;
369
- if (atomic_read (& ring -> pending ))
370
- return - EBUSY ;
371
- }
395
+ if (atomic_read (& nlk -> mapped ))
396
+ return - EBUSY ;
397
+ if (atomic_read (& ring -> pending ))
398
+ return - EBUSY ;
372
399
373
400
if (req -> nm_block_nr ) {
374
401
if (ring -> pg_vec != NULL )
@@ -400,31 +427,19 @@ static int netlink_set_ring(struct sock *sk, struct nl_mmap_req *req,
400
427
return - EINVAL ;
401
428
}
402
429
403
- err = - EBUSY ;
404
430
mutex_lock (& nlk -> pg_vec_lock );
405
- if (closing || atomic_read (& nlk -> mapped ) == 0 ) {
406
- err = 0 ;
407
- spin_lock_bh (& queue -> lock );
408
-
409
- ring -> frame_max = req -> nm_frame_nr - 1 ;
410
- ring -> head = 0 ;
411
- ring -> frame_size = req -> nm_frame_size ;
412
- ring -> pg_vec_pages = req -> nm_block_size / PAGE_SIZE ;
413
-
414
- swap (ring -> pg_vec_len , req -> nm_block_nr );
415
- swap (ring -> pg_vec_order , order );
416
- swap (ring -> pg_vec , pg_vec );
417
-
418
- __skb_queue_purge (queue );
419
- spin_unlock_bh (& queue -> lock );
420
-
421
- WARN_ON (atomic_read (& nlk -> mapped ));
431
+ if (atomic_read (& nlk -> mapped ) == 0 ) {
432
+ __netlink_set_ring (sk , req , tx_ring , pg_vec , order );
433
+ mutex_unlock (& nlk -> pg_vec_lock );
434
+ return 0 ;
422
435
}
436
+
423
437
mutex_unlock (& nlk -> pg_vec_lock );
424
438
425
439
if (pg_vec )
426
440
free_pg_vec (pg_vec , order , req -> nm_block_nr );
427
- return err ;
441
+
442
+ return - EBUSY ;
428
443
}
429
444
430
445
static void netlink_mm_open (struct vm_area_struct * vma )
@@ -893,10 +908,10 @@ static void netlink_sock_destruct(struct sock *sk)
893
908
894
909
memset (& req , 0 , sizeof (req ));
895
910
if (nlk -> rx_ring .pg_vec )
896
- netlink_set_ring (sk , & req , true, false );
911
+ __netlink_set_ring (sk , & req , false, NULL , 0 );
897
912
memset (& req , 0 , sizeof (req ));
898
913
if (nlk -> tx_ring .pg_vec )
899
- netlink_set_ring (sk , & req , true, true );
914
+ __netlink_set_ring (sk , & req , true, NULL , 0 );
900
915
}
901
916
#endif /* CONFIG_NETLINK_MMAP */
902
917
@@ -2190,7 +2205,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
2190
2205
return - EINVAL ;
2191
2206
if (copy_from_user (& req , optval , sizeof (req )))
2192
2207
return - EFAULT ;
2193
- err = netlink_set_ring (sk , & req , false,
2208
+ err = netlink_set_ring (sk , & req ,
2194
2209
optname == NETLINK_TX_RING );
2195
2210
break ;
2196
2211
}
0 commit comments