43
43
static void update_pages_handler (struct work_struct * work );
44
44
45
45
struct ring_buffer_meta {
46
+ unsigned long head_buffer ;
47
+ unsigned long commit_buffer ;
48
+ __u32 subbuf_size ;
49
+ __u32 nr_subbufs ;
50
+ int buffers [];
46
51
};
47
52
48
53
/*
@@ -501,6 +506,7 @@ struct ring_buffer_per_cpu {
501
506
struct mutex mapping_lock ;
502
507
unsigned long * subbuf_ids ; /* ID to subbuf VA */
503
508
struct trace_buffer_meta * meta_page ;
509
+ struct ring_buffer_meta * ring_meta ;
504
510
505
511
/* ring buffer pages to update, > 0 to add, < 0 to remove */
506
512
long nr_pages_to_update ;
@@ -1261,6 +1267,11 @@ static void rb_head_page_activate(struct ring_buffer_per_cpu *cpu_buffer)
1261
1267
* Set the previous list pointer to have the HEAD flag.
1262
1268
*/
1263
1269
rb_set_list_to_head (head -> list .prev );
1270
+
1271
+ if (cpu_buffer -> ring_meta ) {
1272
+ struct ring_buffer_meta * meta = cpu_buffer -> ring_meta ;
1273
+ meta -> head_buffer = (unsigned long )head -> page ;
1274
+ }
1264
1275
}
1265
1276
1266
1277
static void rb_list_head_clear (struct list_head * list )
@@ -1515,51 +1526,127 @@ rb_range_align_subbuf(unsigned long addr, int subbuf_size, int nr_subbufs)
1515
1526
}
1516
1527
1517
1528
/*
1518
- * Return a specific sub-buffer for a given @cpu defined by @idx .
1529
+ * Return the ring_buffer_meta for a given @cpu.
1519
1530
*/
1520
- static void * rb_range_buffer (struct trace_buffer * buffer , int cpu , int nr_pages , int idx )
1531
+ static void * rb_range_meta (struct trace_buffer * buffer , int nr_pages , int cpu )
1521
1532
{
1522
- unsigned long ptr ;
1523
1533
int subbuf_size = buffer -> subbuf_size + BUF_PAGE_HDR_SIZE ;
1534
+ unsigned long ptr = buffer -> range_addr_start ;
1535
+ struct ring_buffer_meta * meta ;
1524
1536
int nr_subbufs ;
1525
1537
1526
- /* Include the reader page */
1527
- nr_subbufs = nr_pages + 1 ;
1538
+ if (!ptr )
1539
+ return NULL ;
1540
+
1541
+ /* When nr_pages passed in is zero, the first meta has already been initialized */
1542
+ if (!nr_pages ) {
1543
+ meta = (struct ring_buffer_meta * )ptr ;
1544
+ nr_subbufs = meta -> nr_subbufs ;
1545
+ } else {
1546
+ meta = NULL ;
1547
+ /* Include the reader page */
1548
+ nr_subbufs = nr_pages + 1 ;
1549
+ }
1528
1550
1529
1551
/*
1530
1552
* The first chunk may not be subbuffer aligned, where as
1531
1553
* the rest of the chunks are.
1532
1554
*/
1533
- ptr = buffer -> range_addr_start ;
1534
- ptr = rb_range_align_subbuf (ptr , subbuf_size , nr_subbufs );
1535
1555
if (cpu ) {
1536
- unsigned long p ;
1537
-
1538
- ptr += subbuf_size * nr_subbufs ;
1539
-
1540
- /* Save the beginning of this CPU chunk */
1541
- p = ptr ;
1542
-
1543
1556
ptr = rb_range_align_subbuf (ptr , subbuf_size , nr_subbufs );
1557
+ ptr += subbuf_size * nr_subbufs ;
1544
1558
1545
1559
/* We can use multiplication to find chunks greater than 1 */
1546
1560
if (cpu > 1 ) {
1547
1561
unsigned long size ;
1562
+ unsigned long p ;
1548
1563
1564
+ /* Save the beginning of this CPU chunk */
1565
+ p = ptr ;
1566
+ ptr = rb_range_align_subbuf (ptr , subbuf_size , nr_subbufs );
1549
1567
ptr += subbuf_size * nr_subbufs ;
1550
1568
1551
1569
/* Now all chunks after this are the same size */
1552
1570
size = ptr - p ;
1553
1571
ptr += size * (cpu - 2 );
1554
-
1555
- ptr = rb_range_align_subbuf (ptr , subbuf_size , nr_subbufs );
1556
1572
}
1557
1573
}
1558
- if (ptr + subbuf_size * nr_subbufs > buffer -> range_addr_end )
1574
+ return (void * )ptr ;
1575
+ }
1576
+
1577
+ /* Return the start of subbufs given the meta pointer */
1578
+ static void * rb_subbufs_from_meta (struct ring_buffer_meta * meta )
1579
+ {
1580
+ int subbuf_size = meta -> subbuf_size ;
1581
+ unsigned long ptr ;
1582
+
1583
+ ptr = (unsigned long )meta ;
1584
+ ptr = rb_range_align_subbuf (ptr , subbuf_size , meta -> nr_subbufs );
1585
+
1586
+ return (void * )ptr ;
1587
+ }
1588
+
1589
+ /*
1590
+ * Return a specific sub-buffer for a given @cpu defined by @idx.
1591
+ */
1592
+ static void * rb_range_buffer (struct ring_buffer_per_cpu * cpu_buffer , int idx )
1593
+ {
1594
+ struct ring_buffer_meta * meta ;
1595
+ unsigned long ptr ;
1596
+ int subbuf_size ;
1597
+
1598
+ meta = rb_range_meta (cpu_buffer -> buffer , 0 , cpu_buffer -> cpu );
1599
+ if (!meta )
1600
+ return NULL ;
1601
+
1602
+ if (WARN_ON_ONCE (idx >= meta -> nr_subbufs ))
1559
1603
return NULL ;
1604
+
1605
+ subbuf_size = meta -> subbuf_size ;
1606
+
1607
+ /* Map this buffer to the order that's in meta->buffers[] */
1608
+ idx = meta -> buffers [idx ];
1609
+
1610
+ ptr = (unsigned long )rb_subbufs_from_meta (meta );
1611
+
1612
+ ptr += subbuf_size * idx ;
1613
+ if (ptr + subbuf_size > cpu_buffer -> buffer -> range_addr_end )
1614
+ return NULL ;
1615
+
1560
1616
return (void * )ptr ;
1561
1617
}
1562
1618
1619
+ static void rb_range_meta_init (struct trace_buffer * buffer , int nr_pages )
1620
+ {
1621
+ struct ring_buffer_meta * meta ;
1622
+ void * subbuf ;
1623
+ int cpu ;
1624
+ int i ;
1625
+
1626
+ for (cpu = 0 ; cpu < nr_cpu_ids ; cpu ++ ) {
1627
+ meta = rb_range_meta (buffer , nr_pages , cpu );
1628
+
1629
+ meta -> nr_subbufs = nr_pages + 1 ;
1630
+ meta -> subbuf_size = PAGE_SIZE ;
1631
+
1632
+ subbuf = rb_subbufs_from_meta (meta );
1633
+
1634
+ /*
1635
+ * The buffers[] array holds the order of the sub-buffers
1636
+ * that are after the meta data. The sub-buffers may
1637
+ * be swapped out when read and inserted into a different
1638
+ * location of the ring buffer. Although their addresses
1639
+ * remain the same, the buffers[] array contains the
1640
+ * index into the sub-buffers holding their actual order.
1641
+ */
1642
+ for (i = 0 ; i < meta -> nr_subbufs ; i ++ ) {
1643
+ meta -> buffers [i ] = i ;
1644
+ rb_init_page (subbuf );
1645
+ subbuf += meta -> subbuf_size ;
1646
+ }
1647
+ }
1648
+ }
1649
+
1563
1650
static int __rb_allocate_pages (struct ring_buffer_per_cpu * cpu_buffer ,
1564
1651
long nr_pages , struct list_head * pages )
1565
1652
{
@@ -1600,7 +1687,6 @@ static int __rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
1600
1687
set_current_oom_origin ();
1601
1688
for (i = 0 ; i < nr_pages ; i ++ ) {
1602
1689
struct page * page ;
1603
- int cpu = cpu_buffer -> cpu ;
1604
1690
1605
1691
bpage = kzalloc_node (ALIGN (sizeof (* bpage ), cache_line_size ()),
1606
1692
mflags , cpu_to_node (cpu_buffer -> cpu ));
@@ -1617,20 +1703,21 @@ static int __rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
1617
1703
1618
1704
if (buffer -> range_addr_start ) {
1619
1705
/* A range was given. Use that for the buffer page */
1620
- bpage -> page = rb_range_buffer (buffer , cpu , nr_pages , i + 1 );
1706
+ bpage -> page = rb_range_buffer (cpu_buffer , i + 1 );
1621
1707
if (!bpage -> page )
1622
1708
goto free_pages ;
1623
1709
bpage -> range = 1 ;
1710
+ bpage -> id = i + 1 ;
1624
1711
} else {
1625
1712
page = alloc_pages_node (cpu_to_node (cpu_buffer -> cpu ),
1626
1713
mflags | __GFP_COMP | __GFP_ZERO ,
1627
1714
cpu_buffer -> buffer -> subbuf_order );
1628
1715
if (!page )
1629
1716
goto free_pages ;
1630
1717
bpage -> page = page_address (page );
1718
+ rb_init_page (bpage -> page );
1631
1719
}
1632
1720
bpage -> order = cpu_buffer -> buffer -> subbuf_order ;
1633
- rb_init_page (bpage -> page );
1634
1721
1635
1722
if (user_thread && fatal_signal_pending (current ))
1636
1723
goto free_pages ;
@@ -1711,7 +1798,13 @@ rb_allocate_cpu_buffer(struct trace_buffer *buffer, long nr_pages, int cpu)
1711
1798
cpu_buffer -> reader_page = bpage ;
1712
1799
1713
1800
if (buffer -> range_addr_start ) {
1714
- bpage -> page = rb_range_buffer (buffer , cpu , nr_pages , 0 );
1801
+ /*
1802
+ * Range mapped buffers have the same restrictions as memory
1803
+ * mapped ones do.
1804
+ */
1805
+ cpu_buffer -> mapped = 1 ;
1806
+ cpu_buffer -> ring_meta = rb_range_meta (buffer , nr_pages , cpu );
1807
+ bpage -> page = rb_range_buffer (cpu_buffer , 0 );
1715
1808
if (!bpage -> page )
1716
1809
goto fail_free_reader ;
1717
1810
bpage -> range = 1 ;
@@ -1722,8 +1815,8 @@ rb_allocate_cpu_buffer(struct trace_buffer *buffer, long nr_pages, int cpu)
1722
1815
if (!page )
1723
1816
goto fail_free_reader ;
1724
1817
bpage -> page = page_address (page );
1818
+ rb_init_page (bpage -> page );
1725
1819
}
1726
- rb_init_page (bpage -> page );
1727
1820
1728
1821
INIT_LIST_HEAD (& cpu_buffer -> reader_page -> list );
1729
1822
INIT_LIST_HEAD (& cpu_buffer -> new_pages );
@@ -1737,6 +1830,10 @@ rb_allocate_cpu_buffer(struct trace_buffer *buffer, long nr_pages, int cpu)
1737
1830
cpu_buffer -> tail_page = cpu_buffer -> commit_page = cpu_buffer -> head_page ;
1738
1831
1739
1832
rb_head_page_activate (cpu_buffer );
1833
+ if (cpu_buffer -> ring_meta ) {
1834
+ struct ring_buffer_meta * meta = cpu_buffer -> ring_meta ;
1835
+ meta -> commit_buffer = meta -> head_buffer ;
1836
+ }
1740
1837
1741
1838
return cpu_buffer ;
1742
1839
@@ -1856,6 +1953,8 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
1856
1953
nr_pages -- ;
1857
1954
buffer -> range_addr_start = start ;
1858
1955
buffer -> range_addr_end = end ;
1956
+
1957
+ rb_range_meta_init (buffer , nr_pages );
1859
1958
} else {
1860
1959
1861
1960
/* need at least two pages */
@@ -2544,6 +2643,52 @@ static void rb_inc_iter(struct ring_buffer_iter *iter)
2544
2643
iter -> next_event = 0 ;
2545
2644
}
2546
2645
2646
+ /* Return the index into the sub-buffers for a given sub-buffer */
2647
+ static int rb_meta_subbuf_idx (struct ring_buffer_meta * meta , void * subbuf )
2648
+ {
2649
+ void * subbuf_array ;
2650
+
2651
+ subbuf_array = (void * )meta + sizeof (int ) * meta -> nr_subbufs ;
2652
+ subbuf_array = (void * )ALIGN ((unsigned long )subbuf_array , meta -> subbuf_size );
2653
+ return (subbuf - subbuf_array ) / meta -> subbuf_size ;
2654
+ }
2655
+
2656
+ static void rb_update_meta_head (struct ring_buffer_per_cpu * cpu_buffer ,
2657
+ struct buffer_page * next_page )
2658
+ {
2659
+ struct ring_buffer_meta * meta = cpu_buffer -> ring_meta ;
2660
+ unsigned long old_head = (unsigned long )next_page -> page ;
2661
+ unsigned long new_head ;
2662
+
2663
+ rb_inc_page (& next_page );
2664
+ new_head = (unsigned long )next_page -> page ;
2665
+
2666
+ /*
2667
+ * Only move it forward once, if something else came in and
2668
+ * moved it forward, then we don't want to touch it.
2669
+ */
2670
+ (void )cmpxchg (& meta -> head_buffer , old_head , new_head );
2671
+ }
2672
+
2673
+ static void rb_update_meta_reader (struct ring_buffer_per_cpu * cpu_buffer ,
2674
+ struct buffer_page * reader )
2675
+ {
2676
+ struct ring_buffer_meta * meta = cpu_buffer -> ring_meta ;
2677
+ void * old_reader = cpu_buffer -> reader_page -> page ;
2678
+ void * new_reader = reader -> page ;
2679
+ int id ;
2680
+
2681
+ id = reader -> id ;
2682
+ cpu_buffer -> reader_page -> id = id ;
2683
+ reader -> id = 0 ;
2684
+
2685
+ meta -> buffers [0 ] = rb_meta_subbuf_idx (meta , new_reader );
2686
+ meta -> buffers [id ] = rb_meta_subbuf_idx (meta , old_reader );
2687
+
2688
+ /* The head pointer is the one after the reader */
2689
+ rb_update_meta_head (cpu_buffer , reader );
2690
+ }
2691
+
2547
2692
/*
2548
2693
* rb_handle_head_page - writer hit the head page
2549
2694
*
@@ -2593,6 +2738,8 @@ rb_handle_head_page(struct ring_buffer_per_cpu *cpu_buffer,
2593
2738
local_sub (rb_page_commit (next_page ), & cpu_buffer -> entries_bytes );
2594
2739
local_inc (& cpu_buffer -> pages_lost );
2595
2740
2741
+ if (cpu_buffer -> ring_meta )
2742
+ rb_update_meta_head (cpu_buffer , next_page );
2596
2743
/*
2597
2744
* The entries will be zeroed out when we move the
2598
2745
* tail page.
@@ -3154,6 +3301,10 @@ rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer)
3154
3301
local_set (& cpu_buffer -> commit_page -> page -> commit ,
3155
3302
rb_page_write (cpu_buffer -> commit_page ));
3156
3303
rb_inc_page (& cpu_buffer -> commit_page );
3304
+ if (cpu_buffer -> ring_meta ) {
3305
+ struct ring_buffer_meta * meta = cpu_buffer -> ring_meta ;
3306
+ meta -> commit_buffer = (unsigned long )cpu_buffer -> commit_page -> page ;
3307
+ }
3157
3308
/* add barrier to keep gcc from optimizing too much */
3158
3309
barrier ();
3159
3310
}
@@ -4771,6 +4922,9 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
4771
4922
if (!ret )
4772
4923
goto spin ;
4773
4924
4925
+ if (cpu_buffer -> ring_meta )
4926
+ rb_update_meta_reader (cpu_buffer , reader );
4927
+
4774
4928
/*
4775
4929
* Yay! We succeeded in replacing the page.
4776
4930
*
@@ -5451,11 +5605,16 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
5451
5605
cpu_buffer -> lost_events = 0 ;
5452
5606
cpu_buffer -> last_overrun = 0 ;
5453
5607
5454
- if (cpu_buffer -> user_mapped )
5455
- rb_update_meta_page (cpu_buffer );
5456
-
5457
5608
rb_head_page_activate (cpu_buffer );
5458
5609
cpu_buffer -> pages_removed = 0 ;
5610
+
5611
+ if (cpu_buffer -> mapped ) {
5612
+ rb_update_meta_page (cpu_buffer );
5613
+ if (cpu_buffer -> ring_meta ) {
5614
+ struct ring_buffer_meta * meta = cpu_buffer -> ring_meta ;
5615
+ meta -> commit_buffer = meta -> head_buffer ;
5616
+ }
5617
+ }
5459
5618
}
5460
5619
5461
5620
/* Must have disabled the cpu buffer then done a synchronize_rcu */
0 commit comments