diff options
-rw-r--r-- | include/linux/ring_buffer.h | 29 | ||||
-rw-r--r-- | kernel/trace/ring_buffer.c | 125 |
2 files changed, 133 insertions, 21 deletions
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index e1b7b2173885..f0aa486d131c 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h | |||
@@ -68,9 +68,38 @@ ring_buffer_event_time_delta(struct ring_buffer_event *event) | |||
68 | return event->time_delta; | 68 | return event->time_delta; |
69 | } | 69 | } |
70 | 70 | ||
71 | /* | ||
72 | * ring_buffer_event_discard can discard any event in the ring buffer. | ||
73 | * it is up to the caller to protect against a reader from | ||
74 | * consuming it or a writer from wrapping and replacing it. | ||
75 | * | ||
76 | * No external protection is needed if this is called before | ||
77 | * the event is commited. But in that case it would be better to | ||
78 | * use ring_buffer_discard_commit. | ||
79 | * | ||
80 | * Note, if an event that has not been committed is discarded | ||
81 | * with ring_buffer_event_discard, it must still be committed. | ||
82 | */ | ||
71 | void ring_buffer_event_discard(struct ring_buffer_event *event); | 83 | void ring_buffer_event_discard(struct ring_buffer_event *event); |
72 | 84 | ||
73 | /* | 85 | /* |
86 | * ring_buffer_discard_commit will remove an event that has not | ||
87 | * ben committed yet. If this is used, then ring_buffer_unlock_commit | ||
88 | * must not be called on the discarded event. This function | ||
89 | * will try to remove the event from the ring buffer completely | ||
90 | * if another event has not been written after it. | ||
91 | * | ||
92 | * Example use: | ||
93 | * | ||
94 | * if (some_condition) | ||
95 | * ring_buffer_discard_commit(buffer, event); | ||
96 | * else | ||
97 | * ring_buffer_unlock_commit(buffer, event); | ||
98 | */ | ||
99 | void ring_buffer_discard_commit(struct ring_buffer *buffer, | ||
100 | struct ring_buffer_event *event); | ||
101 | |||
102 | /* | ||
74 | * size is in bytes for each per CPU buffer. | 103 | * size is in bytes for each per CPU buffer. |
75 | */ | 104 | */ |
76 | struct ring_buffer * | 105 | struct ring_buffer * |
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 74a11808c282..f935bd5ec3e8 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -205,27 +205,6 @@ static void rb_event_set_padding(struct ring_buffer_event *event) | |||
205 | event->time_delta = 0; | 205 | event->time_delta = 0; |
206 | } | 206 | } |
207 | 207 | ||
208 | /** | ||
209 | * ring_buffer_event_discard - discard an event in the ring buffer | ||
210 | * @buffer: the ring buffer | ||
211 | * @event: the event to discard | ||
212 | * | ||
213 | * Sometimes a event that is in the ring buffer needs to be ignored. | ||
214 | * This function lets the user discard an event in the ring buffer | ||
215 | * and then that event will not be read later. | ||
216 | * | ||
217 | * Note, it is up to the user to be careful with this, and protect | ||
218 | * against races. If the user discards an event that has been consumed | ||
219 | * it is possible that it could corrupt the ring buffer. | ||
220 | */ | ||
221 | void ring_buffer_event_discard(struct ring_buffer_event *event) | ||
222 | { | ||
223 | event->type = RINGBUF_TYPE_PADDING; | ||
224 | /* time delta must be non zero */ | ||
225 | if (!event->time_delta) | ||
226 | event->time_delta = 1; | ||
227 | } | ||
228 | |||
229 | static unsigned | 208 | static unsigned |
230 | rb_event_data_length(struct ring_buffer_event *event) | 209 | rb_event_data_length(struct ring_buffer_event *event) |
231 | { | 210 | { |
@@ -1571,6 +1550,110 @@ int ring_buffer_unlock_commit(struct ring_buffer *buffer, | |||
1571 | EXPORT_SYMBOL_GPL(ring_buffer_unlock_commit); | 1550 | EXPORT_SYMBOL_GPL(ring_buffer_unlock_commit); |
1572 | 1551 | ||
1573 | /** | 1552 | /** |
1553 | * ring_buffer_event_discard - discard any event in the ring buffer | ||
1554 | * @event: the event to discard | ||
1555 | * | ||
1556 | * Sometimes a event that is in the ring buffer needs to be ignored. | ||
1557 | * This function lets the user discard an event in the ring buffer | ||
1558 | * and then that event will not be read later. | ||
1559 | * | ||
1560 | * Note, it is up to the user to be careful with this, and protect | ||
1561 | * against races. If the user discards an event that has been consumed | ||
1562 | * it is possible that it could corrupt the ring buffer. | ||
1563 | */ | ||
1564 | void ring_buffer_event_discard(struct ring_buffer_event *event) | ||
1565 | { | ||
1566 | event->type = RINGBUF_TYPE_PADDING; | ||
1567 | /* time delta must be non zero */ | ||
1568 | if (!event->time_delta) | ||
1569 | event->time_delta = 1; | ||
1570 | } | ||
1571 | EXPORT_SYMBOL_GPL(ring_buffer_event_discard); | ||
1572 | |||
1573 | /** | ||
1574 | * ring_buffer_commit_discard - discard an event that has not been committed | ||
1575 | * @buffer: the ring buffer | ||
1576 | * @event: non committed event to discard | ||
1577 | * | ||
1578 | * This is similar to ring_buffer_event_discard but must only be | ||
1579 | * performed on an event that has not been committed yet. The difference | ||
1580 | * is that this will also try to free the event from the ring buffer | ||
1581 | * if another event has not been added behind it. | ||
1582 | * | ||
1583 | * If another event has been added behind it, it will set the event | ||
1584 | * up as discarded, and perform the commit. | ||
1585 | * | ||
1586 | * If this function is called, do not call ring_buffer_unlock_commit on | ||
1587 | * the event. | ||
1588 | */ | ||
1589 | void ring_buffer_discard_commit(struct ring_buffer *buffer, | ||
1590 | struct ring_buffer_event *event) | ||
1591 | { | ||
1592 | struct ring_buffer_per_cpu *cpu_buffer; | ||
1593 | unsigned long new_index, old_index; | ||
1594 | struct buffer_page *bpage; | ||
1595 | unsigned long index; | ||
1596 | unsigned long addr; | ||
1597 | int cpu; | ||
1598 | |||
1599 | /* The event is discarded regardless */ | ||
1600 | ring_buffer_event_discard(event); | ||
1601 | |||
1602 | /* | ||
1603 | * This must only be called if the event has not been | ||
1604 | * committed yet. Thus we can assume that preemption | ||
1605 | * is still disabled. | ||
1606 | */ | ||
1607 | RB_WARN_ON(buffer, !preempt_count()); | ||
1608 | |||
1609 | cpu = smp_processor_id(); | ||
1610 | cpu_buffer = buffer->buffers[cpu]; | ||
1611 | |||
1612 | new_index = rb_event_index(event); | ||
1613 | old_index = new_index + rb_event_length(event); | ||
1614 | addr = (unsigned long)event; | ||
1615 | addr &= PAGE_MASK; | ||
1616 | |||
1617 | bpage = cpu_buffer->tail_page; | ||
1618 | |||
1619 | if (bpage == (void *)addr && rb_page_write(bpage) == old_index) { | ||
1620 | /* | ||
1621 | * This is on the tail page. It is possible that | ||
1622 | * a write could come in and move the tail page | ||
1623 | * and write to the next page. That is fine | ||
1624 | * because we just shorten what is on this page. | ||
1625 | */ | ||
1626 | index = local_cmpxchg(&bpage->write, old_index, new_index); | ||
1627 | if (index == old_index) | ||
1628 | goto out; | ||
1629 | } | ||
1630 | |||
1631 | /* | ||
1632 | * The commit is still visible by the reader, so we | ||
1633 | * must increment entries. | ||
1634 | */ | ||
1635 | cpu_buffer->entries++; | ||
1636 | out: | ||
1637 | /* | ||
1638 | * If a write came in and pushed the tail page | ||
1639 | * we still need to update the commit pointer | ||
1640 | * if we were the commit. | ||
1641 | */ | ||
1642 | if (rb_is_commit(cpu_buffer, event)) | ||
1643 | rb_set_commit_to_write(cpu_buffer); | ||
1644 | |||
1645 | /* | ||
1646 | * Only the last preempt count needs to restore preemption. | ||
1647 | */ | ||
1648 | if (preempt_count() == 1) | ||
1649 | ftrace_preempt_enable(per_cpu(rb_need_resched, cpu)); | ||
1650 | else | ||
1651 | preempt_enable_no_resched_notrace(); | ||
1652 | |||
1653 | } | ||
1654 | EXPORT_SYMBOL_GPL(ring_buffer_discard_commit); | ||
1655 | |||
1656 | /** | ||
1574 | * ring_buffer_write - write data to the buffer without reserving | 1657 | * ring_buffer_write - write data to the buffer without reserving |
1575 | * @buffer: The ring buffer to write to. | 1658 | * @buffer: The ring buffer to write to. |
1576 | * @length: The length of the data being written (excluding the event header) | 1659 | * @length: The length of the data being written (excluding the event header) |