linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org,
	"Steven Rostedt (VMware)" <rostedt@goodmis.org>,
	Sasha Levin <sashal@kernel.org>
Subject: [PATCH 4.4 01/64] ring-buffer: Fix recursion protection transitions between interrupt context
Date: Tue, 17 Nov 2020 14:04:24 +0100	[thread overview]
Message-ID: <20201117122106.199383932@linuxfoundation.org> (raw)
In-Reply-To: <20201117122106.144800239@linuxfoundation.org>

From: Steven Rostedt (VMware) <rostedt@goodmis.org>

[ Upstream commit b02414c8f045ab3b9afc816c3735bc98c5c3d262 ]

The recursion protection of the ring buffer depends on preempt_count() to be
correct. But it is possible that the ring buffer gets called after an
interrupt comes in but before it updates the preempt_count(). This will
trigger a false positive in the recursion code.

Use the same trick from the ftrace function callback recursion code which
uses a "transition" bit that gets set, to allow for a single recursion for
to handle transitions between contexts.

Cc: stable@vger.kernel.org
Fixes: 567cd4da54ff4 ("ring-buffer: User context bit recursion checking")
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/trace/ring_buffer.c | 54 +++++++++++++++++++++++++++++++-------
 1 file changed, 44 insertions(+), 10 deletions(-)

diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 1c1ecc1d49ad2..547a3a5ac57b5 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -416,14 +416,16 @@ struct rb_event_info {
 
 /*
  * Used for which event context the event is in.
- *  NMI     = 0
- *  IRQ     = 1
- *  SOFTIRQ = 2
- *  NORMAL  = 3
+ *  TRANSITION = 0
+ *  NMI     = 1
+ *  IRQ     = 2
+ *  SOFTIRQ = 3
+ *  NORMAL  = 4
  *
  * See trace_recursive_lock() comment below for more details.
  */
 enum {
+	RB_CTX_TRANSITION,
 	RB_CTX_NMI,
 	RB_CTX_IRQ,
 	RB_CTX_SOFTIRQ,
@@ -2585,10 +2587,10 @@ rb_wakeups(struct ring_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer)
  * a bit of overhead in something as critical as function tracing,
  * we use a bitmask trick.
  *
- *  bit 0 =  NMI context
- *  bit 1 =  IRQ context
- *  bit 2 =  SoftIRQ context
- *  bit 3 =  normal context.
+ *  bit 1 =  NMI context
+ *  bit 2 =  IRQ context
+ *  bit 3 =  SoftIRQ context
+ *  bit 4 =  normal context.
  *
  * This works because this is the order of contexts that can
  * preempt other contexts. A SoftIRQ never preempts an IRQ
@@ -2611,6 +2613,30 @@ rb_wakeups(struct ring_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer)
  * The least significant bit can be cleared this way, and it
  * just so happens that it is the same bit corresponding to
  * the current context.
+ *
+ * Now the TRANSITION bit breaks the above slightly. The TRANSITION bit
+ * is set when a recursion is detected at the current context, and if
+ * the TRANSITION bit is already set, it will fail the recursion.
+ * This is needed because there's a lag between the changing of
+ * interrupt context and updating the preempt count. In this case,
+ * a false positive will be found. To handle this, one extra recursion
+ * is allowed, and this is done by the TRANSITION bit. If the TRANSITION
+ * bit is already set, then it is considered a recursion and the function
+ * ends. Otherwise, the TRANSITION bit is set, and that bit is returned.
+ *
+ * On the trace_recursive_unlock(), the TRANSITION bit will be the first
+ * to be cleared. Even if it wasn't the context that set it. That is,
+ * if an interrupt comes in while NORMAL bit is set and the ring buffer
+ * is called before preempt_count() is updated, since the check will
+ * be on the NORMAL bit, the TRANSITION bit will then be set. If an
+ * NMI then comes in, it will set the NMI bit, but when the NMI code
+ * does the trace_recursive_unlock() it will clear the TRANSTION bit
+ * and leave the NMI bit set. But this is fine, because the interrupt
+ * code that set the TRANSITION bit will then clear the NMI bit when it
+ * calls trace_recursive_unlock(). If another NMI comes in, it will
+ * set the TRANSITION bit and continue.
+ *
+ * Note: The TRANSITION bit only handles a single transition between context.
  */
 
 static __always_inline int
@@ -2629,8 +2655,16 @@ trace_recursive_lock(struct ring_buffer_per_cpu *cpu_buffer)
 	} else
 		bit = RB_CTX_NORMAL;
 
-	if (unlikely(val & (1 << bit)))
-		return 1;
+	if (unlikely(val & (1 << bit))) {
+		/*
+		 * It is possible that this was called by transitioning
+		 * between interrupt context, and preempt_count() has not
+		 * been updated yet. In this case, use the TRANSITION bit.
+		 */
+		bit = RB_CTX_TRANSITION;
+		if (val & (1 << bit))
+			return 1;
+	}
 
 	val |= (1 << bit);
 	cpu_buffer->current_context = val;
-- 
2.27.0




  reply	other threads:[~2020-11-17 13:06 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-17 13:04 [PATCH 4.4 00/64] 4.4.244-rc1 review Greg Kroah-Hartman
2020-11-17 13:04 ` Greg Kroah-Hartman [this message]
2020-11-17 13:04 ` [PATCH 4.4 02/64] gfs2: Wake up when sd_glock_disposal becomes zero Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 03/64] mm: mempolicy: fix potential pte_unmap_unlock pte error Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 04/64] time: Prevent undefined behaviour in timespec64_to_ns() Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 05/64] btrfs: reschedule when cloning lots of extents Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 06/64] net: xfrm: fix a race condition during allocing spi Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 07/64] perf tools: Add missing swap for ino_generation Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 08/64] ALSA: hda: prevent undefined shift in snd_hdac_ext_bus_get_link() Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 09/64] can: dev: can_get_echo_skb(): prevent call to kfree_skb() in hard IRQ context Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 10/64] can: dev: __can_get_echo_skb(): fix real payload length return value for RTR frames Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 11/64] can: can_create_echo_skb(): fix echo skb generation: always use skb_clone() Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 12/64] can: peak_usb: add range checking in decode operations Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 13/64] can: peak_usb: peak_usb_get_ts_time(): fix timestamp wrapping Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 14/64] Btrfs: fix missing error return if writeback for extent buffer never started Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 15/64] pinctrl: devicetree: Avoid taking direct reference to device name string Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 16/64] i40e: Wrong truncation from u16 to u8 Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 17/64] i40e: Fix of memory leak and integer truncation in i40e_virtchnl.c Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 18/64] geneve: add transport ports in route lookup for geneve Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 19/64] ath9k_htc: Use appropriate rs_datalen type Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 20/64] usb: gadget: goku_udc: fix potential crashes in probe Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 21/64] gfs2: Free rd_bits later in gfs2_clear_rgrpd to fix use-after-free Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 22/64] gfs2: check for live vs. read-only file system in gfs2_fitrim Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 23/64] drm/amdgpu: perform srbm soft reset always on SDMA resume Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 24/64] mac80211: fix use of skb payload instead of header Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 25/64] mac80211: always wind down STA state Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 26/64] cfg80211: regulatory: Fix inconsistent format argument Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 27/64] iommu/amd: Increase interrupt remapping table limit to 512 entries Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 28/64] xfs: fix a missing unlock on error in xfs_fs_map_blocks Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 29/64] of/address: Fix of_node memory leak in of_dma_is_coherent Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 30/64] cosa: Add missing kfree in error path of cosa_write Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 31/64] perf: Fix get_recursion_context() Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 32/64] ext4: correctly report "not supported" for {usr,grp}jquota when !CONFIG_QUOTA Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 33/64] ext4: unlock xattr_sem properly in ext4_inline_data_truncate() Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 34/64] usb: cdc-acm: Add DISABLE_ECHO for Renesas USB Download mode Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 35/64] mei: protect mei_cl_mtu from null dereference Greg Kroah-Hartman
2020-11-17 13:04 ` [PATCH 4.4 36/64] ocfs2: initialize ip_next_orphan Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 37/64] dont dump the threads that had been already exiting when zapped Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 38/64] drm/gma500: Fix out-of-bounds access to struct drm_device.vblank[] Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 39/64] pinctrl: amd: use higher precision for 512 RtcClk Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 40/64] pinctrl: amd: fix incorrect way to disable debounce filter Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 41/64] swiotlb: fix "x86: Dont panic if can not alloc buffer for swiotlb" Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 42/64] IPv6: Set SIT tunnel hard_header_len to zero Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 43/64] net/af_iucv: fix null pointer dereference on shutdown Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 44/64] net/x25: Fix null-ptr-deref in x25_connect Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 45/64] net: Update window_clamp if SOCK_RCVBUF is set Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 46/64] random32: make prandom_u32() output unpredictable Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 47/64] x86/speculation: Allow IBPB to be conditionally enabled on CPUs with always-on STIBP Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 48/64] xen/events: avoid removing an event channel while handling it Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 49/64] xen/events: add a proper barrier to 2-level uevent unmasking Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 50/64] xen/events: fix race in evtchn_fifo_unmask() Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 51/64] xen/events: add a new "late EOI" evtchn framework Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 52/64] xen/blkback: use lateeoi irq binding Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 53/64] xen/netback: " Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 54/64] xen/scsiback: " Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 55/64] xen/pciback: " Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 56/64] xen/events: switch user event channels to lateeoi model Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 57/64] xen/events: use a common cpu hotplug hook for event channels Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 58/64] xen/events: defer eoi in case of excessive number of events Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 59/64] xen/events: block rogue events for some time Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 60/64] perf/core: Fix race in the perf_mmap_close() function Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 61/64] Revert "kernel/reboot.c: convert simple_strtoul to kstrtoint" Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 62/64] reboot: fix overflow parsing reboot cpu number Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 63/64] ext4: fix leaking sysfs kobject after failed mount Greg Kroah-Hartman
2020-11-17 13:05 ` [PATCH 4.4 64/64] Convert trailing spaces and periods in path components Greg Kroah-Hartman
2020-11-17 18:27 ` [PATCH 4.4 00/64] 4.4.244-rc1 review Pavel Machek
2020-11-18 11:25 ` Naresh Kamboju
2020-11-18 15:22 ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201117122106.199383932@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).