aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ring_buffer.h29
-rw-r--r--kernel/trace/ring_buffer.c125
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 */
71void ring_buffer_event_discard(struct ring_buffer_event *event); 83void 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 */
99void 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 */
76struct ring_buffer * 105struct 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 */
221void 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
229static unsigned 208static unsigned
230rb_event_data_length(struct ring_buffer_event *event) 209rb_event_data_length(struct ring_buffer_event *event)
231{ 210{
@@ -1571,6 +1550,110 @@ int ring_buffer_unlock_commit(struct ring_buffer *buffer,
1571EXPORT_SYMBOL_GPL(ring_buffer_unlock_commit); 1550EXPORT_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 */
1564void 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}
1571EXPORT_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 */
1589void 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}
1654EXPORT_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)