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, stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Julien Grall <julien@xen.org>, Juergen Gross <jgross@suse.com>,
	Jan Beulich <jbeulich@suse.com>, Wei Liu <wl@xen.org>
Subject: [PATCH 4.4 53/64] xen/netback: use lateeoi irq binding
Date: Tue, 17 Nov 2020 14:05:16 +0100	[thread overview]
Message-ID: <20201117122108.779628325@linuxfoundation.org> (raw)
In-Reply-To: <20201117122106.144800239@linuxfoundation.org>

From: Juergen Gross <jgross@suse.com>

commit 23025393dbeb3b8b3b60ebfa724cdae384992e27 upstream.

In order to reduce the chance for the system becoming unresponsive due
to event storms triggered by a misbehaving netfront use the lateeoi
irq binding for netback and unmask the event channel only just before
going to sleep waiting for new events.

Make sure not to issue an EOI when none is pending by introducing an
eoi_pending element to struct xenvif_queue.

When no request has been consumed set the spurious flag when sending
the EOI for an interrupt.

This is part of XSA-332.

Cc: stable@vger.kernel.org
Reported-by: Julien Grall <julien@xen.org>
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Wei Liu <wl@xen.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/xen-netback/common.h    |   39 +++++++++++++++++++++++
 drivers/net/xen-netback/interface.c |   59 +++++++++++++++++++++++++++++++-----
 drivers/net/xen-netback/netback.c   |   17 +++++++---
 3 files changed, 103 insertions(+), 12 deletions(-)

--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -137,6 +137,20 @@ struct xenvif_queue { /* Per-queue data
 	char name[QUEUE_NAME_SIZE]; /* DEVNAME-qN */
 	struct xenvif *vif; /* Parent VIF */
 
+	/*
+	 * TX/RX common EOI handling.
+	 * When feature-split-event-channels = 0, interrupt handler sets
+	 * NETBK_COMMON_EOI, otherwise NETBK_RX_EOI and NETBK_TX_EOI are set
+	 * by the RX and TX interrupt handlers.
+	 * RX and TX handler threads will issue an EOI when either
+	 * NETBK_COMMON_EOI or their specific bits (NETBK_RX_EOI or
+	 * NETBK_TX_EOI) are set and they will reset those bits.
+	 */
+	atomic_t eoi_pending;
+#define NETBK_RX_EOI		0x01
+#define NETBK_TX_EOI		0x02
+#define NETBK_COMMON_EOI	0x04
+
 	/* Use NAPI for guest TX */
 	struct napi_struct napi;
 	/* When feature-split-event-channels = 0, tx_irq = rx_irq. */
@@ -317,6 +331,7 @@ void xenvif_kick_thread(struct xenvif_qu
 
 int xenvif_dealloc_kthread(void *data);
 
+bool xenvif_have_rx_work(struct xenvif_queue *queue, bool test_kthread);
 void xenvif_rx_queue_tail(struct xenvif_queue *queue, struct sk_buff *skb);
 
 void xenvif_carrier_on(struct xenvif *vif);
@@ -353,4 +368,28 @@ void xenvif_skb_zerocopy_complete(struct
 bool xenvif_mcast_match(struct xenvif *vif, const u8 *addr);
 void xenvif_mcast_addr_list_free(struct xenvif *vif);
 
+#include <linux/atomic.h>
+
+static inline int xenvif_atomic_fetch_or(int i, atomic_t *v)
+{
+	int c, old;
+
+	c = v->counter;
+	while ((old = cmpxchg(&v->counter, c, c | i)) != c)
+		c = old;
+
+	return c;
+}
+
+static inline int xenvif_atomic_fetch_andnot(int i, atomic_t *v)
+{
+	int c, old;
+
+	c = v->counter;
+	while ((old = cmpxchg(&v->counter, c, c & ~i)) != c)
+		c = old;
+
+	return c;
+}
+
 #endif /* __XEN_NETBACK__COMMON_H__ */
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -76,12 +76,28 @@ int xenvif_schedulable(struct xenvif *vi
 		!vif->disabled;
 }
 
+static bool xenvif_handle_tx_interrupt(struct xenvif_queue *queue)
+{
+	bool rc;
+
+	rc = RING_HAS_UNCONSUMED_REQUESTS(&queue->tx);
+	if (rc)
+		napi_schedule(&queue->napi);
+	return rc;
+}
+
 static irqreturn_t xenvif_tx_interrupt(int irq, void *dev_id)
 {
 	struct xenvif_queue *queue = dev_id;
+	int old;
 
-	if (RING_HAS_UNCONSUMED_REQUESTS(&queue->tx))
-		napi_schedule(&queue->napi);
+	old = xenvif_atomic_fetch_or(NETBK_TX_EOI, &queue->eoi_pending);
+	WARN(old & NETBK_TX_EOI, "Interrupt while EOI pending\n");
+
+	if (!xenvif_handle_tx_interrupt(queue)) {
+		atomic_andnot(NETBK_TX_EOI, &queue->eoi_pending);
+		xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS);
+	}
 
 	return IRQ_HANDLED;
 }
@@ -115,19 +131,46 @@ static int xenvif_poll(struct napi_struc
 	return work_done;
 }
 
+static bool xenvif_handle_rx_interrupt(struct xenvif_queue *queue)
+{
+	bool rc;
+
+	rc = xenvif_have_rx_work(queue, false);
+	if (rc)
+		xenvif_kick_thread(queue);
+	return rc;
+}
+
 static irqreturn_t xenvif_rx_interrupt(int irq, void *dev_id)
 {
 	struct xenvif_queue *queue = dev_id;
+	int old;
 
-	xenvif_kick_thread(queue);
+	old = xenvif_atomic_fetch_or(NETBK_RX_EOI, &queue->eoi_pending);
+	WARN(old & NETBK_RX_EOI, "Interrupt while EOI pending\n");
+
+	if (!xenvif_handle_rx_interrupt(queue)) {
+		atomic_andnot(NETBK_RX_EOI, &queue->eoi_pending);
+		xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS);
+	}
 
 	return IRQ_HANDLED;
 }
 
 irqreturn_t xenvif_interrupt(int irq, void *dev_id)
 {
-	xenvif_tx_interrupt(irq, dev_id);
-	xenvif_rx_interrupt(irq, dev_id);
+	struct xenvif_queue *queue = dev_id;
+	int old;
+
+	old = xenvif_atomic_fetch_or(NETBK_COMMON_EOI, &queue->eoi_pending);
+	WARN(old, "Interrupt while EOI pending\n");
+
+	/* Use bitwise or as we need to call both functions. */
+	if ((!xenvif_handle_tx_interrupt(queue) |
+	     !xenvif_handle_rx_interrupt(queue))) {
+		atomic_andnot(NETBK_COMMON_EOI, &queue->eoi_pending);
+		xen_irq_lateeoi(irq, XEN_EOI_FLAG_SPURIOUS);
+	}
 
 	return IRQ_HANDLED;
 }
@@ -555,7 +598,7 @@ int xenvif_connect(struct xenvif_queue *
 
 	if (tx_evtchn == rx_evtchn) {
 		/* feature-split-event-channels == 0 */
-		err = bind_interdomain_evtchn_to_irqhandler(
+		err = bind_interdomain_evtchn_to_irqhandler_lateeoi(
 			queue->vif->domid, tx_evtchn, xenvif_interrupt, 0,
 			queue->name, queue);
 		if (err < 0)
@@ -566,7 +609,7 @@ int xenvif_connect(struct xenvif_queue *
 		/* feature-split-event-channels == 1 */
 		snprintf(queue->tx_irq_name, sizeof(queue->tx_irq_name),
 			 "%s-tx", queue->name);
-		err = bind_interdomain_evtchn_to_irqhandler(
+		err = bind_interdomain_evtchn_to_irqhandler_lateeoi(
 			queue->vif->domid, tx_evtchn, xenvif_tx_interrupt, 0,
 			queue->tx_irq_name, queue);
 		if (err < 0)
@@ -576,7 +619,7 @@ int xenvif_connect(struct xenvif_queue *
 
 		snprintf(queue->rx_irq_name, sizeof(queue->rx_irq_name),
 			 "%s-rx", queue->name);
-		err = bind_interdomain_evtchn_to_irqhandler(
+		err = bind_interdomain_evtchn_to_irqhandler_lateeoi(
 			queue->vif->domid, rx_evtchn, xenvif_rx_interrupt, 0,
 			queue->rx_irq_name, queue);
 		if (err < 0)
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -670,6 +670,10 @@ void xenvif_napi_schedule_or_enable_even
 
 	if (more_to_do)
 		napi_schedule(&queue->napi);
+	else if (xenvif_atomic_fetch_andnot(NETBK_TX_EOI | NETBK_COMMON_EOI,
+				     &queue->eoi_pending) &
+		 (NETBK_TX_EOI | NETBK_COMMON_EOI))
+		xen_irq_lateeoi(queue->tx_irq, 0);
 }
 
 static void tx_add_credit(struct xenvif_queue *queue)
@@ -2010,14 +2014,14 @@ static bool xenvif_rx_queue_ready(struct
 	return queue->stalled && prod - cons >= 1;
 }
 
-static bool xenvif_have_rx_work(struct xenvif_queue *queue)
+bool xenvif_have_rx_work(struct xenvif_queue *queue, bool test_kthread)
 {
 	return (!skb_queue_empty(&queue->rx_queue)
 		&& xenvif_rx_ring_slots_available(queue))
 		|| (queue->vif->stall_timeout &&
 		    (xenvif_rx_queue_stalled(queue)
 		     || xenvif_rx_queue_ready(queue)))
-		|| kthread_should_stop()
+		|| (test_kthread && kthread_should_stop())
 		|| queue->vif->disabled;
 }
 
@@ -2048,15 +2052,20 @@ static void xenvif_wait_for_rx_work(stru
 {
 	DEFINE_WAIT(wait);
 
-	if (xenvif_have_rx_work(queue))
+	if (xenvif_have_rx_work(queue, true))
 		return;
 
 	for (;;) {
 		long ret;
 
 		prepare_to_wait(&queue->wq, &wait, TASK_INTERRUPTIBLE);
-		if (xenvif_have_rx_work(queue))
+		if (xenvif_have_rx_work(queue, true))
 			break;
+		if (xenvif_atomic_fetch_andnot(NETBK_RX_EOI | NETBK_COMMON_EOI,
+					&queue->eoi_pending) &
+		    (NETBK_RX_EOI | NETBK_COMMON_EOI))
+			xen_irq_lateeoi(queue->rx_irq, 0);
+
 		ret = schedule_timeout(xenvif_rx_queue_timeout(queue));
 		if (!ret)
 			break;



  parent reply	other threads:[~2020-11-17 13:08 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 ` [PATCH 4.4 01/64] ring-buffer: Fix recursion protection transitions between interrupt context Greg Kroah-Hartman
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 ` Greg Kroah-Hartman [this message]
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=20201117122108.779628325@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=jbeulich@suse.com \
    --cc=jgross@suse.com \
    --cc=julien@xen.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=wl@xen.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).