@@ -1252,7 +1252,7 @@ static inline unsigned long rb_page_write(struct buffer_page *bpage)
1252
1252
return local_read (& bpage -> write ) & RB_WRITE_MASK ;
1253
1253
}
1254
1254
1255
- static void
1255
+ static int
1256
1256
rb_remove_pages (struct ring_buffer_per_cpu * cpu_buffer , unsigned int nr_pages )
1257
1257
{
1258
1258
struct list_head * tail_page , * to_remove , * next_page ;
@@ -1359,46 +1359,97 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned int nr_pages)
1359
1359
} while (to_remove_page != last_page );
1360
1360
1361
1361
RB_WARN_ON (cpu_buffer , nr_removed );
1362
+
1363
+ return nr_removed == 0 ;
1362
1364
}
1363
1365
1364
- static void
1365
- rb_insert_pages (struct ring_buffer_per_cpu * cpu_buffer ,
1366
- struct list_head * pages , unsigned nr_pages )
1366
+ static int
1367
+ rb_insert_pages (struct ring_buffer_per_cpu * cpu_buffer )
1367
1368
{
1368
- struct buffer_page * bpage ;
1369
- struct list_head * p ;
1370
- unsigned i ;
1369
+ struct list_head * pages = & cpu_buffer -> new_pages ;
1370
+ int retries , success ;
1371
1371
1372
1372
raw_spin_lock_irq (& cpu_buffer -> reader_lock );
1373
- /* stop the writers while inserting pages */
1374
- atomic_inc (& cpu_buffer -> record_disabled );
1375
- rb_head_page_deactivate (cpu_buffer );
1373
+ /*
1374
+ * We are holding the reader lock, so the reader page won't be swapped
1375
+ * in the ring buffer. Now we are racing with the writer trying to
1376
+ * move head page and the tail page.
1377
+ * We are going to adapt the reader page update process where:
1378
+ * 1. We first splice the start and end of list of new pages between
1379
+ * the head page and its previous page.
1380
+ * 2. We cmpxchg the prev_page->next to point from head page to the
1381
+ * start of new pages list.
1382
+ * 3. Finally, we update the head->prev to the end of new list.
1383
+ *
1384
+ * We will try this process 10 times, to make sure that we don't keep
1385
+ * spinning.
1386
+ */
1387
+ retries = 10 ;
1388
+ success = 0 ;
1389
+ while (retries -- ) {
1390
+ struct list_head * head_page , * prev_page , * r ;
1391
+ struct list_head * last_page , * first_page ;
1392
+ struct list_head * head_page_with_bit ;
1376
1393
1377
- for (i = 0 ; i < nr_pages ; i ++ ) {
1378
- if (RB_WARN_ON (cpu_buffer , list_empty (pages )))
1379
- goto out ;
1380
- p = pages -> next ;
1381
- bpage = list_entry (p , struct buffer_page , list );
1382
- list_del_init (& bpage -> list );
1383
- list_add_tail (& bpage -> list , cpu_buffer -> pages );
1394
+ head_page = & rb_set_head_page (cpu_buffer )-> list ;
1395
+ prev_page = head_page -> prev ;
1396
+
1397
+ first_page = pages -> next ;
1398
+ last_page = pages -> prev ;
1399
+
1400
+ head_page_with_bit = (struct list_head * )
1401
+ ((unsigned long )head_page | RB_PAGE_HEAD );
1402
+
1403
+ last_page -> next = head_page_with_bit ;
1404
+ first_page -> prev = prev_page ;
1405
+
1406
+ r = cmpxchg (& prev_page -> next , head_page_with_bit , first_page );
1407
+
1408
+ if (r == head_page_with_bit ) {
1409
+ /*
1410
+ * yay, we replaced the page pointer to our new list,
1411
+ * now, we just have to update to head page's prev
1412
+ * pointer to point to end of list
1413
+ */
1414
+ head_page -> prev = last_page ;
1415
+ success = 1 ;
1416
+ break ;
1417
+ }
1384
1418
}
1385
- rb_reset_cpu (cpu_buffer );
1386
- rb_check_pages (cpu_buffer );
1387
1419
1388
- out :
1389
- atomic_dec (& cpu_buffer -> record_disabled );
1420
+ if (success )
1421
+ INIT_LIST_HEAD (pages );
1422
+ /*
1423
+ * If we weren't successful in adding in new pages, warn and stop
1424
+ * tracing
1425
+ */
1426
+ RB_WARN_ON (cpu_buffer , !success );
1390
1427
raw_spin_unlock_irq (& cpu_buffer -> reader_lock );
1428
+
1429
+ /* free pages if they weren't inserted */
1430
+ if (!success ) {
1431
+ struct buffer_page * bpage , * tmp ;
1432
+ list_for_each_entry_safe (bpage , tmp , & cpu_buffer -> new_pages ,
1433
+ list ) {
1434
+ list_del_init (& bpage -> list );
1435
+ free_buffer_page (bpage );
1436
+ }
1437
+ }
1438
+ return success ;
1391
1439
}
1392
1440
1393
1441
static void rb_update_pages (struct ring_buffer_per_cpu * cpu_buffer )
1394
1442
{
1443
+ int success ;
1444
+
1395
1445
if (cpu_buffer -> nr_pages_to_update > 0 )
1396
- rb_insert_pages (cpu_buffer , & cpu_buffer -> new_pages ,
1397
- cpu_buffer -> nr_pages_to_update );
1446
+ success = rb_insert_pages (cpu_buffer );
1398
1447
else
1399
- rb_remove_pages (cpu_buffer , - cpu_buffer -> nr_pages_to_update );
1448
+ success = rb_remove_pages (cpu_buffer ,
1449
+ - cpu_buffer -> nr_pages_to_update );
1400
1450
1401
- cpu_buffer -> nr_pages += cpu_buffer -> nr_pages_to_update ;
1451
+ if (success )
1452
+ cpu_buffer -> nr_pages += cpu_buffer -> nr_pages_to_update ;
1402
1453
}
1403
1454
1404
1455
static void update_pages_handler (struct work_struct * work )
@@ -3772,6 +3823,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
3772
3823
cpu_buffer -> commit_page = cpu_buffer -> head_page ;
3773
3824
3774
3825
INIT_LIST_HEAD (& cpu_buffer -> reader_page -> list );
3826
+ INIT_LIST_HEAD (& cpu_buffer -> new_pages );
3775
3827
local_set (& cpu_buffer -> reader_page -> write , 0 );
3776
3828
local_set (& cpu_buffer -> reader_page -> entries , 0 );
3777
3829
local_set (& cpu_buffer -> reader_page -> page -> commit , 0 );
0 commit comments