From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org,
Stephen Hemminger <sthemmin@microsoft.com>,
"K. Y. Srinivasan" <kys@microsoft.com>,
Haiyang Zhang <haiyangz@microsoft.com>,
Dexuan Cui <decui@microsoft.com>
Subject: [PATCH 4.14 58/67] Drivers: hv: vmbus: Offload the handling of channels to two workqueues
Date: Tue, 11 Dec 2018 16:41:58 +0100 [thread overview]
Message-ID: <20181211151633.318780100@linuxfoundation.org> (raw)
In-Reply-To: <20181211151630.378216233@linuxfoundation.org>
4.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dexuan Cui <decui@microsoft.com>
commit 37c2578c0c40e286bc0d30bdc05290b2058cf66e upstream.
vmbus_process_offer() mustn't call channel->sc_creation_callback()
directly for sub-channels, because sc_creation_callback() ->
vmbus_open() may never get the host's response to the
OPEN_CHANNEL message (the host may rescind a channel at any time,
e.g. in the case of hot removing a NIC), and vmbus_onoffer_rescind()
may not wake up the vmbus_open() as it's blocked due to a non-zero
vmbus_connection.offer_in_progress, and finally we have a deadlock.
The above is also true for primary channels, if the related device
drivers use sync probing mode by default.
And, usually the handling of primary channels and sub-channels can
depend on each other, so we should offload them to different
workqueues to avoid possible deadlock, e.g. in sync-probing mode,
NIC1's netvsc_subchan_work() can race with NIC2's netvsc_probe() ->
rtnl_lock(), and causes deadlock: the former gets the rtnl_lock
and waits for all the sub-channels to appear, but the latter
can't get the rtnl_lock and this blocks the handling of sub-channels.
The patch can fix the multiple-NIC deadlock described above for
v3.x kernels (e.g. RHEL 7.x) which don't support async-probing
of devices, and v4.4, v4.9, v4.14 and v4.18 which support async-probing
but don't enable async-probing for Hyper-V drivers (yet).
The patch can also fix the hang issue in sub-channel's handling described
above for all versions of kernels, including v4.19 and v4.20-rc4.
So actually the patch should be applied to all the existing kernels,
not only the kernels that have 8195b1396ec8.
Fixes: 8195b1396ec8 ("hv_netvsc: fix deadlock on hotplug")
Cc: stable@vger.kernel.org
Cc: Stephen Hemminger <sthemmin@microsoft.com>
Cc: K. Y. Srinivasan <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Dexuan Cui <decui@microsoft.com>
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hv/channel_mgmt.c | 185 +++++++++++++++++++++++++++++++---------------
drivers/hv/connection.c | 24 +++++
drivers/hv/hyperv_vmbus.h | 7 +
include/linux/hyperv.h | 7 +
4 files changed, 160 insertions(+), 63 deletions(-)
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -444,61 +444,16 @@ void vmbus_free_channels(void)
}
}
-/*
- * vmbus_process_offer - Process the offer by creating a channel/device
- * associated with this offer
- */
-static void vmbus_process_offer(struct vmbus_channel *newchannel)
+/* Note: the function can run concurrently for primary/sub channels. */
+static void vmbus_add_channel_work(struct work_struct *work)
{
- struct vmbus_channel *channel;
- bool fnew = true;
+ struct vmbus_channel *newchannel =
+ container_of(work, struct vmbus_channel, add_channel_work);
+ struct vmbus_channel *primary_channel = newchannel->primary_channel;
unsigned long flags;
u16 dev_type;
int ret;
- /* Make sure this is a new offer */
- mutex_lock(&vmbus_connection.channel_mutex);
-
- /*
- * Now that we have acquired the channel_mutex,
- * we can release the potentially racing rescind thread.
- */
- atomic_dec(&vmbus_connection.offer_in_progress);
-
- list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
- if (!uuid_le_cmp(channel->offermsg.offer.if_type,
- newchannel->offermsg.offer.if_type) &&
- !uuid_le_cmp(channel->offermsg.offer.if_instance,
- newchannel->offermsg.offer.if_instance)) {
- fnew = false;
- break;
- }
- }
-
- if (fnew)
- list_add_tail(&newchannel->listentry,
- &vmbus_connection.chn_list);
-
- mutex_unlock(&vmbus_connection.channel_mutex);
-
- if (!fnew) {
- /*
- * Check to see if this is a sub-channel.
- */
- if (newchannel->offermsg.offer.sub_channel_index != 0) {
- /*
- * Process the sub-channel.
- */
- newchannel->primary_channel = channel;
- spin_lock_irqsave(&channel->lock, flags);
- list_add_tail(&newchannel->sc_list, &channel->sc_list);
- channel->num_sc++;
- spin_unlock_irqrestore(&channel->lock, flags);
- } else {
- goto err_free_chan;
- }
- }
-
dev_type = hv_get_dev_type(newchannel);
init_vp_index(newchannel, dev_type);
@@ -516,21 +471,22 @@ static void vmbus_process_offer(struct v
/*
* This state is used to indicate a successful open
* so that when we do close the channel normally, we
- * can cleanup properly
+ * can cleanup properly.
*/
newchannel->state = CHANNEL_OPEN_STATE;
- if (!fnew) {
- if (channel->sc_creation_callback != NULL)
- channel->sc_creation_callback(newchannel);
+ if (primary_channel != NULL) {
+ /* newchannel is a sub-channel. */
+
+ if (primary_channel->sc_creation_callback != NULL)
+ primary_channel->sc_creation_callback(newchannel);
+
newchannel->probe_done = true;
return;
}
/*
- * Start the process of binding this offer to the driver
- * We need to set the DeviceObject field before calling
- * vmbus_child_dev_add()
+ * Start the process of binding the primary channel to the driver
*/
newchannel->device_obj = vmbus_device_create(
&newchannel->offermsg.offer.if_type,
@@ -559,13 +515,28 @@ static void vmbus_process_offer(struct v
err_deq_chan:
mutex_lock(&vmbus_connection.channel_mutex);
- list_del(&newchannel->listentry);
+
+ /*
+ * We need to set the flag, otherwise
+ * vmbus_onoffer_rescind() can be blocked.
+ */
+ newchannel->probe_done = true;
+
+ if (primary_channel == NULL) {
+ list_del(&newchannel->listentry);
+ } else {
+ spin_lock_irqsave(&primary_channel->lock, flags);
+ list_del(&newchannel->sc_list);
+ spin_unlock_irqrestore(&primary_channel->lock, flags);
+ }
+
mutex_unlock(&vmbus_connection.channel_mutex);
if (newchannel->target_cpu != get_cpu()) {
put_cpu();
smp_call_function_single(newchannel->target_cpu,
- percpu_channel_deq, newchannel, true);
+ percpu_channel_deq,
+ newchannel, true);
} else {
percpu_channel_deq(newchannel);
put_cpu();
@@ -573,14 +544,104 @@ err_deq_chan:
vmbus_release_relid(newchannel->offermsg.child_relid);
-err_free_chan:
free_channel(newchannel);
}
/*
+ * vmbus_process_offer - Process the offer by creating a channel/device
+ * associated with this offer
+ */
+static void vmbus_process_offer(struct vmbus_channel *newchannel)
+{
+ struct vmbus_channel *channel;
+ struct workqueue_struct *wq;
+ unsigned long flags;
+ bool fnew = true;
+
+ mutex_lock(&vmbus_connection.channel_mutex);
+
+ /*
+ * Now that we have acquired the channel_mutex,
+ * we can release the potentially racing rescind thread.
+ */
+ atomic_dec(&vmbus_connection.offer_in_progress);
+
+ list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
+ if (!uuid_le_cmp(channel->offermsg.offer.if_type,
+ newchannel->offermsg.offer.if_type) &&
+ !uuid_le_cmp(channel->offermsg.offer.if_instance,
+ newchannel->offermsg.offer.if_instance)) {
+ fnew = false;
+ break;
+ }
+ }
+
+ if (fnew)
+ list_add_tail(&newchannel->listentry,
+ &vmbus_connection.chn_list);
+ else {
+ /*
+ * Check to see if this is a valid sub-channel.
+ */
+ if (newchannel->offermsg.offer.sub_channel_index == 0) {
+ mutex_unlock(&vmbus_connection.channel_mutex);
+ /*
+ * Don't call free_channel(), because newchannel->kobj
+ * is not initialized yet.
+ */
+ kfree(newchannel);
+ WARN_ON_ONCE(1);
+ return;
+ }
+ /*
+ * Process the sub-channel.
+ */
+ newchannel->primary_channel = channel;
+ spin_lock_irqsave(&channel->lock, flags);
+ list_add_tail(&newchannel->sc_list, &channel->sc_list);
+ spin_unlock_irqrestore(&channel->lock, flags);
+ }
+
+ mutex_unlock(&vmbus_connection.channel_mutex);
+
+ /*
+ * vmbus_process_offer() mustn't call channel->sc_creation_callback()
+ * directly for sub-channels, because sc_creation_callback() ->
+ * vmbus_open() may never get the host's response to the
+ * OPEN_CHANNEL message (the host may rescind a channel at any time,
+ * e.g. in the case of hot removing a NIC), and vmbus_onoffer_rescind()
+ * may not wake up the vmbus_open() as it's blocked due to a non-zero
+ * vmbus_connection.offer_in_progress, and finally we have a deadlock.
+ *
+ * The above is also true for primary channels, if the related device
+ * drivers use sync probing mode by default.
+ *
+ * And, usually the handling of primary channels and sub-channels can
+ * depend on each other, so we should offload them to different
+ * workqueues to avoid possible deadlock, e.g. in sync-probing mode,
+ * NIC1's netvsc_subchan_work() can race with NIC2's netvsc_probe() ->
+ * rtnl_lock(), and causes deadlock: the former gets the rtnl_lock
+ * and waits for all the sub-channels to appear, but the latter
+ * can't get the rtnl_lock and this blocks the handling of
+ * sub-channels.
+ */
+ INIT_WORK(&newchannel->add_channel_work, vmbus_add_channel_work);
+ wq = fnew ? vmbus_connection.handle_primary_chan_wq :
+ vmbus_connection.handle_sub_chan_wq;
+ queue_work(wq, &newchannel->add_channel_work);
+}
+
+/*
* We use this state to statically distribute the channel interrupt load.
*/
static int next_numa_node_id;
+/*
+ * init_vp_index() accesses global variables like next_numa_node_id, and
+ * it can run concurrently for primary channels and sub-channels: see
+ * vmbus_process_offer(), so we need the lock to protect the global
+ * variables.
+ */
+static DEFINE_SPINLOCK(bind_channel_to_cpu_lock);
/*
* Starting with Win8, we can statically distribute the incoming
@@ -618,6 +679,8 @@ static void init_vp_index(struct vmbus_c
return;
}
+ spin_lock(&bind_channel_to_cpu_lock);
+
/*
* Based on the channel affinity policy, we will assign the NUMA
* nodes.
@@ -700,6 +763,8 @@ static void init_vp_index(struct vmbus_c
channel->target_cpu = cur_cpu;
channel->target_vp = hv_cpu_number_to_vp_number(cur_cpu);
+ spin_unlock(&bind_channel_to_cpu_lock);
+
free_cpumask_var(available_mask);
}
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -161,6 +161,20 @@ int vmbus_connect(void)
goto cleanup;
}
+ vmbus_connection.handle_primary_chan_wq =
+ create_workqueue("hv_pri_chan");
+ if (!vmbus_connection.handle_primary_chan_wq) {
+ ret = -ENOMEM;
+ goto cleanup;
+ }
+
+ vmbus_connection.handle_sub_chan_wq =
+ create_workqueue("hv_sub_chan");
+ if (!vmbus_connection.handle_sub_chan_wq) {
+ ret = -ENOMEM;
+ goto cleanup;
+ }
+
INIT_LIST_HEAD(&vmbus_connection.chn_msg_list);
spin_lock_init(&vmbus_connection.channelmsg_lock);
@@ -251,10 +265,14 @@ void vmbus_disconnect(void)
*/
vmbus_initiate_unload(false);
- if (vmbus_connection.work_queue) {
- drain_workqueue(vmbus_connection.work_queue);
+ if (vmbus_connection.handle_sub_chan_wq)
+ destroy_workqueue(vmbus_connection.handle_sub_chan_wq);
+
+ if (vmbus_connection.handle_primary_chan_wq)
+ destroy_workqueue(vmbus_connection.handle_primary_chan_wq);
+
+ if (vmbus_connection.work_queue)
destroy_workqueue(vmbus_connection.work_queue);
- }
if (vmbus_connection.int_page) {
free_pages((unsigned long)vmbus_connection.int_page, 0);
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -327,7 +327,14 @@ struct vmbus_connection {
struct list_head chn_list;
struct mutex channel_mutex;
+ /*
+ * An offer message is handled first on the work_queue, and then
+ * is further handled on handle_primary_chan_wq or
+ * handle_sub_chan_wq.
+ */
struct workqueue_struct *work_queue;
+ struct workqueue_struct *handle_primary_chan_wq;
+ struct workqueue_struct *handle_sub_chan_wq;
};
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -869,6 +869,13 @@ struct vmbus_channel {
bool probe_done;
+ /*
+ * We must offload the handling of the primary/sub channels
+ * from the single-threaded vmbus_connection.work_queue to
+ * two different workqueue, otherwise we can block
+ * vmbus_connection.work_queue and hang: see vmbus_process_offer().
+ */
+ struct work_struct add_channel_work;
};
static inline bool is_hvsock_channel(const struct vmbus_channel *c)
next prev parent reply other threads:[~2018-12-11 15:53 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-11 15:41 [PATCH 4.14 00/67] 4.14.88-stable review Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 01/67] media: omap3isp: Unregister media device as first Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 02/67] iommu/vt-d: Fix NULL pointer dereference in prq_event_thread() Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 03/67] brcmutil: really fix decoding channel info for 160 MHz bandwidth Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 04/67] iommu/ipmmu-vmsa: Fix crash on early domain free Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 05/67] can: rcar_can: Fix erroneous registration Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 06/67] test_firmware: fix error return getting clobbered Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 07/67] HID: input: Ignore battery reported by Symbol DS4308 Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 08/67] batman-adv: Use explicit tvlv padding for ELP packets Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 09/67] batman-adv: Expand merged fragment buffer for full packet Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 10/67] amd/iommu: Fix Guest Virtual APIC Log Tail Address Register Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 11/67] bnx2x: Assign unique DMAE channel number for FW DMAE transactions Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 12/67] qed: Fix PTT leak in qed_drain() Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 13/67] qed: Fix reading wrong value in loop condition Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 14/67] Revert "usb: gadget: ffs: Fix BUG when userland exits with submitted AIO transfers" Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 15/67] net/mlx4_core: Zero out lkey field in SW2HW_MPT fw command Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 16/67] net/mlx4_core: Fix uninitialized variable compilation warning Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 17/67] net/mlx4: Fix UBSAN warning of signed integer overflow Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 18/67] gpio: mockup: fix indicated direction Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 19/67] mtd: rawnand: qcom: Namespace prefix some commands Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 20/67] HID: multitouch: Add pointstick support for Cirque Touchpad Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 21/67] mtd: spi-nor: Fix Cadence QSPI page fault kernel panic Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 22/67] qed: Fix bitmap_weight() check Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 23/67] qed: Fix QM getters to always return a valid pq Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 24/67] net: faraday: ftmac100: remove netif_running(netdev) check before disabling interrupts Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 25/67] iommu/vt-d: Use memunmap to free memremap Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 26/67] flexfiles: use per-mirror specified stateid for IO Greg Kroah-Hartman
2018-12-11 18:48 ` Mkrtchyan, Tigran
2018-12-11 15:41 ` [PATCH 4.14 27/67] ibmvnic: Fix RX queue buffer cleanup Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 28/67] team: no need to do team_notify_peers or team_mcast_rejoin when disabling port Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 29/67] net: amd: add missing of_node_put() Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 30/67] mm: dont warn about allocations which stall for too long Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 31/67] usb: quirk: add no-LPM quirk on SanDisk Ultra Flair device Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 32/67] usb: appledisplay: Add 27" Apple Cinema Display Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 33/67] USB: check usb_get_extra_descriptor for proper size Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 34/67] ALSA: usb-audio: Fix UAF decrement if card has no live interfaces in card.c Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 35/67] ALSA: hda: Add support for AMD Stoney Ridge Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 36/67] ALSA: pcm: Fix starvation on down_write_nonblock() Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 37/67] ALSA: pcm: Call snd_pcm_unlink() conditionally at closing Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 38/67] ALSA: pcm: Fix interval evaluation with openmin/max Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 39/67] ALSA: hda/realtek - Fix speaker output regression on Thinkpad T570 Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 40/67] virtio/s390: avoid race on vcdev->config Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 41/67] virtio/s390: fix race in ccw_io_helper() Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 42/67] vhost/vsock: fix use-after-free in network stack callers Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 43/67] SUNRPC: Fix leak of krb5p encode pages Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 44/67] dmaengine: dw: Fix FIFO size for Intel Merrifield Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 45/67] dmaengine: cppi41: delete channel from pending list when stop channel Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 46/67] ARM: 8806/1: kprobes: Fix false positive with FORTIFY_SOURCE Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 47/67] xhci: workaround CSS timeout on AMD SNPS 3.0 xHC Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 48/67] xhci: Prevent U1/U2 link pm states if exit latency is too long Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 49/67] f2fs: fix to do sanity check with block address in main area v2 Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 50/67] swiotlb: clean up reporting Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 51/67] Staging: lustre: remove two build warnings Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 52/67] staging: atomisp: remove "fun" strncpy warning Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 53/67] cifs: Fix separator when building path from dentry Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 54/67] staging: rtl8712: Fix possible buffer overrun Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 55/67] Revert commit ef9209b642f "staging: rtl8723bs: Fix indenting errors and an off-by-one mistake in core/rtw_mlme_ext.c" Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 56/67] drm/amdgpu: update mc firmware image for polaris12 variants Greg Kroah-Hartman
2018-12-11 15:41 ` [PATCH 4.14 57/67] drm/amdgpu/gmc8: update MC firmware for polaris Greg Kroah-Hartman
2018-12-11 15:41 ` Greg Kroah-Hartman [this message]
2018-12-11 15:41 ` [PATCH 4.14 59/67] tty: serial: 8250_mtk: always resume the device in probe Greg Kroah-Hartman
2018-12-11 15:42 ` [PATCH 4.14 60/67] tty: do not set TTY_IO_ERROR flag if console port Greg Kroah-Hartman
2018-12-11 15:42 ` [PATCH 4.14 61/67] kgdboc: fix KASAN global-out-of-bounds bug in param_set_kgdboc_var() Greg Kroah-Hartman
2018-12-11 15:42 ` [PATCH 4.14 62/67] libnvdimm, pfn: Pad pfn namespaces relative to other regions Greg Kroah-Hartman
2018-12-11 15:42 ` [PATCH 4.14 63/67] mac80211_hwsim: Timer should be initialized before device registered Greg Kroah-Hartman
2018-12-11 15:42 ` [PATCH 4.14 64/67] mac80211: Clear beacon_int in ieee80211_do_stop Greg Kroah-Hartman
2018-12-11 15:42 ` [PATCH 4.14 65/67] mac80211: ignore tx status for PS stations in ieee80211_tx_status_ext Greg Kroah-Hartman
2018-12-11 15:42 ` [PATCH 4.14 66/67] mac80211: fix reordering of buffered broadcast packets Greg Kroah-Hartman
2018-12-11 15:42 ` [PATCH 4.14 67/67] mac80211: ignore NullFunc frames in the duplicate detection Greg Kroah-Hartman
2018-12-11 21:33 ` [PATCH 4.14 00/67] 4.14.88-stable review kernelci.org bot
2018-12-11 23:59 ` shuah
2018-12-12 6:37 ` Naresh Kamboju
2018-12-12 18:50 ` 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=20181211151633.318780100@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=decui@microsoft.com \
--cc=haiyangz@microsoft.com \
--cc=kys@microsoft.com \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=sthemmin@microsoft.com \
/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