History

Merge tag 'trace-v6.2-rc7-3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull tracing fix from Steven Rostedt: "Fix race that causes a warning of corrupt ring buffer With the change that allows to read the "trace" file without disabling writing to the ring buffer, there was an integrity check of the ring buffer in the iterator read code, that expected the ring buffer to be write disabled. This caused the integrity check to trigger when stress reading the "trace" file while writing was happening. The integrity check is a bit aggressive (and has never triggered in practice). Change it so that it checks just the integrity of the linked pages without clearing the flags inside the pointers. This removes the warning that was being triggered" [ Heh. This was supposed to have gone in last week before the 6.2 release, but Steven forgot to actually add me to the participants of the pull request, so here it is, a week later - Linus ] * tag 'trace-v6.2-rc7-3' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: ring-buffer: Handle race between rb_move_tail and rb_check_pages

Linus Torvalds committed 3 years ago

Commit 91914232 parents d392e49 8843e061 file · +10 −32Browse files

Showing the changes to kernel (1 of 1 file). Show all

Unified · Split

kernel/trace/ring_buffer.c+10−32
@@ -1580,19 +1580,6 @@ static int rb_check_bpage(struct ring_buffer_per_cpu *cpu_buffer, · 1579 unmodified lines
1580 return 0;1580 return 0;
1581}1581}
1582 1582
1583/**
1584 * rb_check_list - make sure a pointer to a list has the last bits zero
1585 */
1586static int rb_check_list(struct ring_buffer_per_cpu *cpu_buffer,
1587 struct list_head *list)
1588{
1589 if (RB_WARN_ON(cpu_buffer, rb_list_head(list->prev) != list->prev))
1590 return 1;
1591 if (RB_WARN_ON(cpu_buffer, rb_list_head(list->next) != list->next))
1592 return 1;
1593 return 0;
1594}
1595
1596/**1583/**
1597 * rb_check_pages - integrity check of buffer pages1584 * rb_check_pages - integrity check of buffer pages
1598 * @cpu_buffer: CPU buffer with pages to test1585 * @cpu_buffer: CPU buffer with pages to test
@@ -1602,36 +1589,27 @@ static int rb_check_list(struct ring_buffer_per_cpu *cpu_buffer, · 3 unmodified lines
1602 */1589 */
1603static int rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer)1590static int rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer)
1604{1591{
1605 struct list_head *head = cpu_buffer->pages;1592 struct list_head *head = rb_list_head(cpu_buffer->pages);
1606 struct buffer_page *bpage, *tmp;1593 struct list_head *tmp;
1607 1594
1608 /* Reset the head page if it exists */1595 if (RB_WARN_ON(cpu_buffer,
1609 if (cpu_buffer->head_page)1596 rb_list_head(rb_list_head(head->next)->prev) != head))
1610 rb_set_head_page(cpu_buffer);
1611
1612 rb_head_page_deactivate(cpu_buffer);
1613
1614 if (RB_WARN_ON(cpu_buffer, head->next->prev != head))
1615 return -1;
1616 if (RB_WARN_ON(cpu_buffer, head->prev->next != head))
1617 return -1;1597 return -1;
1618 1598
1619 if (rb_check_list(cpu_buffer, head))1599 if (RB_WARN_ON(cpu_buffer,
1600 rb_list_head(rb_list_head(head->prev)->next) != head))
1620 return -1;1601 return -1;
1621 1602
1622 list_for_each_entry_safe(bpage, tmp, head, list) {1603 for (tmp = rb_list_head(head->next); tmp != head; tmp = rb_list_head(tmp->next)) {
1623 if (RB_WARN_ON(cpu_buffer,1604 if (RB_WARN_ON(cpu_buffer,
1624 bpage->list.next->prev != &bpage->list))1605 rb_list_head(rb_list_head(tmp->next)->prev) != tmp))
1625 return -1;1606 return -1;
1607
1626 if (RB_WARN_ON(cpu_buffer,1608 if (RB_WARN_ON(cpu_buffer,
1627 bpage->list.prev->next != &bpage->list))1609 rb_list_head(rb_list_head(tmp->prev)->next) != tmp))
1628 return -1;
1629 if (rb_check_list(cpu_buffer, &bpage->list))
1630 return -1;1610 return -1;
1631 }1611 }
1632 1612
1633 rb_head_page_activate(cpu_buffer);
1634
1635 return 0;1613 return 0;
1636}1614}
1637 1615