This is the start of the stable review cycle for the 4.14.295 release.
There are 38 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Wed, 28 Sep 2022 16:35:25 +0000.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.14.295-r…
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.14.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Linux 4.14.295-rc2
Dongliang Mu <mudongliangabcd(a)gmail.com>
media: em28xx: initialize refcount before kref_get
Jan Kara <jack(a)suse.cz>
ext4: make directory inode spreading reflect flexbg size
Vitaly Kuznetsov <vkuznets(a)redhat.com>
Drivers: hv: Never allocate anything besides framebuffer from framebuffer memory region
Stefan Haberland <sth(a)linux.ibm.com>
s390/dasd: fix Oops in dasd_alias_get_start_dev due to missing pavgroup
Ilpo Järvinen <ilpo.jarvinen(a)linux.intel.com>
serial: tegra: Use uart_xmit_advance(), fixes icount.tx accounting
Ilpo Järvinen <ilpo.jarvinen(a)linux.intel.com>
serial: Create uart_xmit_advance()
Sean Anderson <seanga2(a)gmail.com>
net: sunhme: Fix packet reception for len < RX_COPY_THRESHOLD
Adrian Hunter <adrian.hunter(a)intel.com>
perf kcore_copy: Do not check /proc/modules is unchanged
Marc Kleine-Budde <mkl(a)pengutronix.de>
can: gs_usb: gs_can_open(): fix race dev->can.state condition
Florian Westphal <fw(a)strlen.de>
netfilter: ebtables: fix memory leak when blob is malformed
Liang He <windhl(a)126.com>
of: mdio: Add of_node_put() when breaking out of for_each_xx
Randy Dunlap <rdunlap(a)infradead.org>
MIPS: lantiq: export clk_get_io() for lantiq_wdt.ko
Benjamin Poirier <bpoirier(a)nvidia.com>
net: team: Unsync device addresses on ndo_stop
Lu Wei <luwei32(a)huawei.com>
ipvlan: Fix out-of-bound bugs caused by unset skb->mac_header
Brett Creeley <brett.creeley(a)intel.com>
iavf: Fix cached head and tail value for iavf_get_tx_pending
David Leadbeater <dgl(a)dgl.cx>
netfilter: nf_conntrack_irc: Tighten matching on DCC message
Igor Ryzhov <iryzhov(a)nfware.com>
netfilter: nf_conntrack_sip: fix ct_sip_walk_headers
Fabio Estevam <festevam(a)denx.de>
arm64: dts: rockchip: Remove 'enable-active-low' from rk3399-puma
Chao Yu <chao.yu(a)oppo.com>
mm/slub: fix to return errno if kmalloc() fails
Kai Vehmanen <kai.vehmanen(a)linux.intel.com>
ALSA: hda: add Intel 5 Series / 3400 PCI DID
Mohan Kumar <mkumard(a)nvidia.com>
ALSA: hda/tegra: set depop delay for tegra
jerry meng <jerry-meng(a)foxmail.com>
USB: serial: option: add Quectel RM520N
Carl Yin(殷张成) <carl.yin(a)quectel.com>
USB: serial: option: add Quectel BG95 0x0203 composition
Alan Stern <stern(a)rowland.harvard.edu>
USB: core: Fix RST error in hub.c
Siddh Raman Pant <code(a)siddh.me>
wifi: mac80211: Fix UAF in ieee80211_scan_rx()
Takashi Iwai <tiwai(a)suse.de>
ALSA: hda/sigmatel: Fix unused variable warning for beep power change
Hyunwoo Kim <imv4bel(a)gmail.com>
video: fbdev: pxa3xx-gcu: Fix integer overflow in pxa3xx_gcu_write
Youling Tang <tangyouling(a)loongson.cn>
mksysmap: Fix the mismatch of 'L0' symbols in System.map
Alexander Sverdlin <alexander.sverdlin(a)nokia.com>
MIPS: OCTEON: irq: Fix octeon_irq_force_ciu_mapping()
jerry.meng <jerry-meng(a)foxmail.com>
net: usb: qmi_wwan: add Quectel RM520N
Takashi Iwai <tiwai(a)suse.de>
ALSA: hda/sigmatel: Keep power up while beep is enabled
Xiaolei Wang <xiaolei.wang(a)windriver.com>
regulator: pfuze100: Fix the global-out-of-bounds access in pfuze100_regulator_probe()
Takashi Iwai <tiwai(a)suse.de>
ASoC: nau8824: Fix semaphore unbalance at error paths
Stefan Metzmacher <metze(a)samba.org>
cifs: don't send down the destination address to sendmsg for a SOCK_STREAM
Yang Yingliang <yangyingliang(a)huawei.com>
parisc: ccio-dma: Add missing iounmap in error path in ccio_probe()
Stuart Menefy <stuart.menefy(a)mathembedded.com>
drm/meson: Correct OSD1 global alpha value
Pali Rohár <pali(a)kernel.org>
gpio: mpc8xxx: Fix support for IRQ_TYPE_LEVEL_LOW flow_type in mpc85xx
Sergey Shtylyov <s.shtylyov(a)omp.ru>
of: fdt: fix off-by-one error in unflatten_dt_nodes()
-------------
Diffstat:
Makefile | 4 ++--
arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 1 -
arch/mips/cavium-octeon/octeon-irq.c | 10 ++++++++
arch/mips/lantiq/clk.c | 1 +
drivers/gpio/gpio-mpc8xxx.c | 1 +
drivers/gpu/drm/meson/meson_plane.c | 2 +-
drivers/hv/vmbus_drv.c | 10 +++++++-
drivers/media/usb/em28xx/em28xx-cards.c | 4 ++--
drivers/net/can/usb/gs_usb.c | 4 ++--
drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 5 +++-
drivers/net/ethernet/sun/sunhme.c | 4 ++--
drivers/net/ipvlan/ipvlan_core.c | 6 +++--
drivers/net/team/team.c | 24 ++++++++++++++-----
drivers/net/usb/qmi_wwan.c | 1 +
drivers/of/fdt.c | 2 +-
drivers/of/of_mdio.c | 1 +
drivers/parisc/ccio-dma.c | 1 +
drivers/regulator/pfuze100-regulator.c | 2 +-
drivers/s390/block/dasd_alias.c | 9 +++++--
drivers/tty/serial/serial-tegra.c | 5 ++--
drivers/usb/core/hub.c | 2 +-
drivers/usb/serial/option.c | 6 +++++
drivers/video/fbdev/pxa3xx-gcu.c | 2 +-
fs/cifs/transport.c | 4 ++--
fs/ext4/ialloc.c | 2 +-
include/linux/serial_core.h | 17 ++++++++++++++
mm/slub.c | 5 +++-
net/bridge/netfilter/ebtables.c | 4 +++-
net/mac80211/scan.c | 11 +++++----
net/netfilter/nf_conntrack_irc.c | 34 ++++++++++++++++++++++-----
net/netfilter/nf_conntrack_sip.c | 4 ++--
scripts/mksysmap | 2 +-
sound/pci/hda/hda_intel.c | 2 ++
sound/pci/hda/patch_hdmi.c | 1 +
sound/pci/hda/patch_sigmatel.c | 24 +++++++++++++++++++
sound/soc/codecs/nau8824.c | 17 ++++++++------
tools/perf/util/symbol-elf.c | 7 ++----
37 files changed, 182 insertions(+), 59 deletions(-)
From: "Steven Rostedt (Google)" <rostedt(a)goodmis.org>
If a process is waiting on the ring buffer for data, there currently isn't
a clean way to force it to wake up. Add an ioctl call that will force any
tasks that are waiting on the trace_pipe_raw file to wake up.
Cc: stable(a)vger.kernel.org
Fixes: e30f53aad2202 ("tracing: Do not busy wait in buffer splice")
Signed-off-by: Steven Rostedt (Google) <rostedt(a)goodmis.org>
---
kernel/trace/trace.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index e101b0764b39..fdbcabfdd2c4 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -8349,12 +8349,30 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
return ret;
}
+/* An ioctl call to the ring buffer file will wake up all waiters */
+static long tracing_buffers_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct ftrace_buffer_info *info = file->private_data;
+ struct trace_iterator *iter = &info->iter;
+
+ mutex_lock(&trace_types_lock);
+
+ iter->wait_index++;
+ /* Make sure the waiters see the new wait_index */
+ smp_wmb();
+
+ ring_buffer_wake_waiters(iter->array_buffer->buffer, iter->cpu_file);
+ mutex_unlock(&trace_types_lock);
+ return 0;
+}
+
static const struct file_operations tracing_buffers_fops = {
.open = tracing_buffers_open,
.read = tracing_buffers_read,
.poll = tracing_buffers_poll,
.release = tracing_buffers_release,
.splice_read = tracing_buffers_splice_read,
+ .unlocked_ioctl = tracing_buffers_ioctl,
.llseek = no_llseek,
};
--
2.35.1
From: "Steven Rostedt (Google)" <rostedt(a)goodmis.org>
When the file that represents the ring buffer is closed, there may be
waiters waiting on more input from the ring buffer. Call
ring_buffer_wake_waiters() to wake up any waiters when the file is
closed.
Cc: stable(a)vger.kernel.org
Fixes: e30f53aad2202 ("tracing: Do not busy wait in buffer splice")
Signed-off-by: Steven Rostedt (Google) <rostedt(a)goodmis.org>
---
include/linux/trace_events.h | 1 +
kernel/trace/trace.c | 15 +++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index 8401dec93c15..20749bd9db71 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -92,6 +92,7 @@ struct trace_iterator {
unsigned int temp_size;
char *fmt; /* modified format holder */
unsigned int fmt_size;
+ long wait_index;
/* trace_seq for __print_flags() and __print_symbolic() etc. */
struct trace_seq tmp_seq;
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index aed7ea6e6045..e101b0764b39 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -8160,6 +8160,12 @@ static int tracing_buffers_release(struct inode *inode, struct file *file)
__trace_array_put(iter->tr);
+ iter->wait_index++;
+ /* Make sure the waiters see the new wait_index */
+ smp_wmb();
+
+ ring_buffer_wake_waiters(iter->array_buffer->buffer, iter->cpu_file);
+
if (info->spare)
ring_buffer_free_read_page(iter->array_buffer->buffer,
info->spare_cpu, info->spare);
@@ -8313,6 +8319,8 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
/* did we read anything? */
if (!spd.nr_pages) {
+ long wait_index;
+
if (ret)
goto out;
@@ -8320,10 +8328,17 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
if ((file->f_flags & O_NONBLOCK) || (flags & SPLICE_F_NONBLOCK))
goto out;
+ wait_index = READ_ONCE(iter->wait_index);
+
ret = wait_on_pipe(iter, iter->tr->buffer_percent);
if (ret)
goto out;
+ /* Make sure we see the new wait_index */
+ smp_rmb();
+ if (wait_index != iter->wait_index)
+ goto out;
+
goto again;
}
--
2.35.1
From: "Steven Rostedt (Google)" <rostedt(a)goodmis.org>
On closing of a file that represents a ring buffer or flushing the file,
there may be waiters on the ring buffer that needs to be woken up and exit
the ring_buffer_wait() function.
Add ring_buffer_wake_waiters() to wake up the waiters on the ring buffer
and allow them to exit the wait loop.
Cc: stable(a)vger.kernel.org
Fixes: 15693458c4bc0 ("tracing/ring-buffer: Move poll wake ups into ring buffer code")
Signed-off-by: Steven Rostedt (Google) <rostedt(a)goodmis.org>
---
include/linux/ring_buffer.h | 2 +-
kernel/trace/ring_buffer.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index dac53fd3afea..2504df9a0453 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -101,7 +101,7 @@ __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *k
int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full);
__poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
struct file *filp, poll_table *poll_table);
-
+void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu);
#define RING_BUFFER_ALL_CPUS -1
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 5a7d818ca3ea..677812b8fae0 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -413,6 +413,7 @@ struct rb_irq_work {
struct irq_work work;
wait_queue_head_t waiters;
wait_queue_head_t full_waiters;
+ long wait_index;
bool waiters_pending;
bool full_waiters_pending;
bool wakeup_full;
@@ -924,6 +925,32 @@ static void rb_wake_up_waiters(struct irq_work *work)
}
}
+/**
+ * ring_buffer_wake_waiters - wake up any waiters on this ring buffer
+ * @buffer: The ring buffer to wake waiters on
+ *
+ * In the case of a file that represents a ring buffer is closing,
+ * it is prudent to wake up any waiters that are on this.
+ */
+void ring_buffer_wake_waiters(struct trace_buffer *buffer, int cpu)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ struct rb_irq_work *rbwork;
+
+ if (cpu == RING_BUFFER_ALL_CPUS) {
+ rbwork = &buffer->irq_work;
+ } else {
+ cpu_buffer = buffer->buffers[cpu];
+ rbwork = &cpu_buffer->irq_work;
+ }
+
+ rbwork->wait_index++;
+ /* make sure the waiters see the new index */
+ smp_wmb();
+
+ rb_wake_up_waiters(&rbwork->work);
+}
+
/**
* ring_buffer_wait - wait for input to the ring buffer
* @buffer: buffer to wait on
@@ -939,6 +966,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
struct ring_buffer_per_cpu *cpu_buffer;
DEFINE_WAIT(wait);
struct rb_irq_work *work;
+ long wait_index;
int ret = 0;
/*
@@ -957,6 +985,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
work = &cpu_buffer->irq_work;
}
+ wait_index = READ_ONCE(work->wait_index);
while (true) {
if (full)
@@ -1021,6 +1050,11 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
}
schedule();
+
+ /* Make sure to see the new wait index */
+ smp_rmb();
+ if (wait_index != work->wait_index)
+ break;
}
if (full)
--
2.35.1
From: "Steven Rostedt (Google)" <rostedt(a)goodmis.org>
The wake up waiters only checks the "wakeup_full" variable and not the
"full_waiters_pending". The full_waiters_pending is set when a waiter is
added to the wait queue. The wakeup_full is only set when an event is
triggered, and it clears the full_waiters_pending to avoid multiple calls
to irq_work_queue().
The irq_work callback really needs to check both wakeup_full as well as
full_waiters_pending such that this code can be used to wake up waiters
when a file is closed that represents the ring buffer and the waiters need
to be woken up.
Cc: stable(a)vger.kernel.org
Fixes: 15693458c4bc0 ("tracing/ring-buffer: Move poll wake ups into ring buffer code")
Signed-off-by: Steven Rostedt (Google) <rostedt(a)goodmis.org>
---
kernel/trace/ring_buffer.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 02db92c9eb1b..5a7d818ca3ea 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -917,8 +917,9 @@ static void rb_wake_up_waiters(struct irq_work *work)
struct rb_irq_work *rbwork = container_of(work, struct rb_irq_work, work);
wake_up_all(&rbwork->waiters);
- if (rbwork->wakeup_full) {
+ if (rbwork->full_waiters_pending || rbwork->wakeup_full) {
rbwork->wakeup_full = false;
+ rbwork->full_waiters_pending = false;
wake_up_all(&rbwork->full_waiters);
}
}
--
2.35.1
From: "Steven Rostedt (Google)" <rostedt(a)goodmis.org>
The logic to know when the shortest waiters on the ring buffer should be
woken up or not has uses a less than instead of a greater than compare,
which causes the shortest_full to actually be the longest.
Cc: stable(a)vger.kernel.org
Fixes: 2c2b0a78b3739 ("ring-buffer: Add percentage of ring buffer full to wake up reader")
Signed-off-by: Steven Rostedt (Google) <rostedt(a)goodmis.org>
---
kernel/trace/ring_buffer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 6b145d48dfd1..02db92c9eb1b 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -1011,7 +1011,7 @@ int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
nr_pages = cpu_buffer->nr_pages;
dirty = ring_buffer_nr_dirty_pages(buffer, cpu);
if (!cpu_buffer->shortest_full ||
- cpu_buffer->shortest_full < full)
+ cpu_buffer->shortest_full > full)
cpu_buffer->shortest_full = full;
raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
if (!pagebusy &&
--
2.35.1
From: Menglong Dong <imagedong(a)tencent.com>
The mptcp socket and its subflow sockets in accept queue can't be
released after the process exit.
While the release of a mptcp socket in listening state, the
corresponding tcp socket will be released too. Meanwhile, the tcp
socket in the unaccept queue will be released too. However, only init
subflow is in the unaccept queue, and the joined subflow is not in the
unaccept queue, which makes the joined subflow won't be released, and
therefore the corresponding unaccepted mptcp socket will not be released
to.
This can be reproduced easily with following steps:
1. create 2 namespace and veth:
$ ip netns add mptcp-client
$ ip netns add mptcp-server
$ sysctl -w net.ipv4.conf.all.rp_filter=0
$ ip netns exec mptcp-client sysctl -w net.mptcp.enabled=1
$ ip netns exec mptcp-server sysctl -w net.mptcp.enabled=1
$ ip link add red-client netns mptcp-client type veth peer red-server \
netns mptcp-server
$ ip -n mptcp-server address add 10.0.0.1/24 dev red-server
$ ip -n mptcp-server address add 192.168.0.1/24 dev red-server
$ ip -n mptcp-client address add 10.0.0.2/24 dev red-client
$ ip -n mptcp-client address add 192.168.0.2/24 dev red-client
$ ip -n mptcp-server link set red-server up
$ ip -n mptcp-client link set red-client up
2. configure the endpoint and limit for client and server:
$ ip -n mptcp-server mptcp endpoint flush
$ ip -n mptcp-server mptcp limits set subflow 2 add_addr_accepted 2
$ ip -n mptcp-client mptcp endpoint flush
$ ip -n mptcp-client mptcp limits set subflow 2 add_addr_accepted 2
$ ip -n mptcp-client mptcp endpoint add 192.168.0.2 dev red-client id \
1 subflow
3. listen and accept on a port, such as 9999. The nc command we used
here is modified, which makes it use mptcp protocol by default.
$ ip netns exec mptcp-server nc -l -k -p 9999
4. open another *two* terminal and use each of them to connect to the
server with the following command:
$ ip netns exec mptcp-client nc 10.0.0.1 9999
Input something after connect to trigger the connection of the second
subflow. So that there are two established mptcp connections, with the
second one still unaccepted.
5. exit all the nc command, and check the tcp socket in server namespace.
And you will find that there is one tcp socket in CLOSE_WAIT state
and can't release forever.
Fix this by closing all of the unaccepted mptcp socket in
mptcp_subflow_queue_clean() with __mptcp_close().
Now, we can ensure that all unaccepted mptcp sockets will be cleaned by
__mptcp_close() before they are released, so mptcp_sock_destruct(), which
is used to clean the unaccepted mptcp socket, is not needed anymore.
The selftests for mptcp is ran for this commit, and no new failures.
Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests")
Fixes: 6aeed9045071 ("mptcp: fix race on unaccepted mptcp sockets")
Cc: stable(a)vger.kernel.org
Reviewed-by: Jiang Biao <benbjiang(a)tencent.com>
Reviewed-by: Mengen Sun <mengensun(a)tencent.com>
Acked-by: Paolo Abeni <pabeni(a)redhat.com>
Signed-off-by: Menglong Dong <imagedong(a)tencent.com>
Signed-off-by: Mat Martineau <mathew.j.martineau(a)linux.intel.com>
---
net/mptcp/protocol.c | 2 +-
net/mptcp/protocol.h | 1 +
net/mptcp/subflow.c | 33 +++++++--------------------------
3 files changed, 9 insertions(+), 27 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index f7690414320a..f8897a70c11d 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2662,7 +2662,7 @@ static void __mptcp_clear_xmit(struct sock *sk)
dfrag_clear(sk, dfrag);
}
-static void mptcp_cancel_work(struct sock *sk)
+void mptcp_cancel_work(struct sock *sk)
{
struct mptcp_sock *msk = mptcp_sk(sk);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 8f123d450c76..8f372b8f059c 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -613,6 +613,7 @@ void mptcp_subflow_queue_clean(struct sock *ssk);
void mptcp_sock_graft(struct sock *sk, struct socket *parent);
struct socket *__mptcp_nmpc_socket(const struct mptcp_sock *msk);
bool __mptcp_close(struct sock *sk, long timeout);
+void mptcp_cancel_work(struct sock *sk);
bool mptcp_addresses_equal(const struct mptcp_addr_info *a,
const struct mptcp_addr_info *b, bool use_port);
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index c7d49fb6e7bd..07dd23d0fe04 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -602,30 +602,6 @@ static bool subflow_hmac_valid(const struct request_sock *req,
return !crypto_memneq(hmac, mp_opt->hmac, MPTCPOPT_HMAC_LEN);
}
-static void mptcp_sock_destruct(struct sock *sk)
-{
- /* if new mptcp socket isn't accepted, it is free'd
- * from the tcp listener sockets request queue, linked
- * from req->sk. The tcp socket is released.
- * This calls the ULP release function which will
- * also remove the mptcp socket, via
- * sock_put(ctx->conn).
- *
- * Problem is that the mptcp socket will be in
- * ESTABLISHED state and will not have the SOCK_DEAD flag.
- * Both result in warnings from inet_sock_destruct.
- */
- if ((1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) {
- sk->sk_state = TCP_CLOSE;
- WARN_ON_ONCE(sk->sk_socket);
- sock_orphan(sk);
- }
-
- /* We don't need to clear msk->subflow, as it's still NULL at this point */
- mptcp_destroy_common(mptcp_sk(sk), 0);
- inet_sock_destruct(sk);
-}
-
static void mptcp_force_close(struct sock *sk)
{
/* the msk is not yet exposed to user-space */
@@ -768,7 +744,6 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
/* new mpc subflow takes ownership of the newly
* created mptcp socket
*/
- new_msk->sk_destruct = mptcp_sock_destruct;
mptcp_sk(new_msk)->setsockopt_seq = ctx->setsockopt_seq;
mptcp_pm_new_connection(mptcp_sk(new_msk), child, 1);
mptcp_token_accept(subflow_req, mptcp_sk(new_msk));
@@ -1763,13 +1738,19 @@ void mptcp_subflow_queue_clean(struct sock *listener_ssk)
for (msk = head; msk; msk = next) {
struct sock *sk = (struct sock *)msk;
- bool slow;
+ bool slow, do_cancel_work;
+ sock_hold(sk);
slow = lock_sock_fast_nested(sk);
next = msk->dl_next;
msk->first = NULL;
msk->dl_next = NULL;
+
+ do_cancel_work = __mptcp_close(sk, 0);
unlock_sock_fast(sk, slow);
+ if (do_cancel_work)
+ mptcp_cancel_work(sk);
+ sock_put(sk);
}
/* we are still under the listener msk socket lock */
--
2.37.3