From: Oliver Hartkopp <socketcan(a)hartkopp.net>
As discussed with Dae R. Jeong and Hillf Danton here [1] the sendmsg()
function in isotp.c might get into a race condition when restoring the
former tx.state from the old_state.
Remove the old_state concept and implement proper locking for the
ISOTP_IDLE transitions in isotp_sendmsg(), inspired by a
simplification idea from Hillf Danton.
Introduce a new tx.state ISOTP_SHUTDOWN and use the same locking
mechanism from isotp_release() which resolves a potential race between
isotp_sendsmg() and isotp_release().
[1] https://lore.kernel.org/linux-can/ZB%2F93xJxq%2FBUqAgG@dragonet
v1: https://lore.kernel.org/all/20230331102114.15164-1-socketcan@hartkopp.net
v2: https://lore.kernel.org/all/20230331123600.3550-1-socketcan@hartkopp.net
take care of signal interrupts for wait_event_interruptible() in
isotp_release()
v3: https://lore.kernel.org/all/20230331130654.9886-1-socketcan@hartkopp.net
take care of signal interrupts for wait_event_interruptible() in
isotp_sendmsg() in the wait_tx_done case
v4: https://lore.kernel.org/all/20230331131935.21465-1-socketcan@hartkopp.net
take care of signal interrupts for wait_event_interruptible() in
isotp_sendmsg() in ALL cases
Cc: Dae R. Jeong <threeearcat(a)gmail.com>
Cc: Hillf Danton <hdanton(a)sina.com>
Signed-off-by: Oliver Hartkopp <socketcan(a)hartkopp.net>
Fixes: 4f027cba8216 ("can: isotp: split tx timer into transmission and timeout")
Link: https://lore.kernel.org/all/20230331131935.21465-1-socketcan@hartkopp.net
Cc: stable(a)vger.kernel.org
[mkl: rephrase commit message]
Signed-off-by: Marc Kleine-Budde <mkl(a)pengutronix.de>
---
net/can/isotp.c | 55 ++++++++++++++++++++++++++++---------------------
1 file changed, 31 insertions(+), 24 deletions(-)
diff --git a/net/can/isotp.c b/net/can/isotp.c
index 281b7766c54e..5761d4ab839d 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -119,7 +119,8 @@ enum {
ISOTP_WAIT_FIRST_FC,
ISOTP_WAIT_FC,
ISOTP_WAIT_DATA,
- ISOTP_SENDING
+ ISOTP_SENDING,
+ ISOTP_SHUTDOWN,
};
struct tpcon {
@@ -880,8 +881,8 @@ static enum hrtimer_restart isotp_tx_timer_handler(struct hrtimer *hrtimer)
txtimer);
struct sock *sk = &so->sk;
- /* don't handle timeouts in IDLE state */
- if (so->tx.state == ISOTP_IDLE)
+ /* don't handle timeouts in IDLE or SHUTDOWN state */
+ if (so->tx.state == ISOTP_IDLE || so->tx.state == ISOTP_SHUTDOWN)
return HRTIMER_NORESTART;
/* we did not get any flow control or echo frame in time */
@@ -918,7 +919,6 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
{
struct sock *sk = sock->sk;
struct isotp_sock *so = isotp_sk(sk);
- u32 old_state = so->tx.state;
struct sk_buff *skb;
struct net_device *dev;
struct canfd_frame *cf;
@@ -928,23 +928,24 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
int off;
int err;
- if (!so->bound)
+ if (!so->bound || so->tx.state == ISOTP_SHUTDOWN)
return -EADDRNOTAVAIL;
+wait_free_buffer:
/* we do not support multiple buffers - for now */
- if (cmpxchg(&so->tx.state, ISOTP_IDLE, ISOTP_SENDING) != ISOTP_IDLE ||
- wq_has_sleeper(&so->wait)) {
- if (msg->msg_flags & MSG_DONTWAIT) {
- err = -EAGAIN;
- goto err_out;
- }
+ if (wq_has_sleeper(&so->wait) && (msg->msg_flags & MSG_DONTWAIT))
+ return -EAGAIN;
- /* wait for complete transmission of current pdu */
- err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
- if (err)
- goto err_out;
+ /* wait for complete transmission of current pdu */
+ err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
+ if (err)
+ goto err_event_drop;
- so->tx.state = ISOTP_SENDING;
+ if (cmpxchg(&so->tx.state, ISOTP_IDLE, ISOTP_SENDING) != ISOTP_IDLE) {
+ if (so->tx.state == ISOTP_SHUTDOWN)
+ return -EADDRNOTAVAIL;
+
+ goto wait_free_buffer;
}
if (!size || size > MAX_MSG_LENGTH) {
@@ -1074,7 +1075,9 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
if (wait_tx_done) {
/* wait for complete transmission of current pdu */
- wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
+ err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
+ if (err)
+ goto err_event_drop;
if (sk->sk_err)
return -sk->sk_err;
@@ -1082,13 +1085,15 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
return size;
+err_event_drop:
+ /* got signal: force tx state machine to be idle */
+ so->tx.state = ISOTP_IDLE;
+ hrtimer_cancel(&so->txfrtimer);
+ hrtimer_cancel(&so->txtimer);
err_out_drop:
/* drop this PDU and unlock a potential wait queue */
- old_state = ISOTP_IDLE;
-err_out:
- so->tx.state = old_state;
- if (so->tx.state == ISOTP_IDLE)
- wake_up_interruptible(&so->wait);
+ so->tx.state = ISOTP_IDLE;
+ wake_up_interruptible(&so->wait);
return err;
}
@@ -1150,10 +1155,12 @@ static int isotp_release(struct socket *sock)
net = sock_net(sk);
/* wait for complete transmission of current pdu */
- wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
+ while (wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE) == 0 &&
+ cmpxchg(&so->tx.state, ISOTP_IDLE, ISOTP_SHUTDOWN) != ISOTP_IDLE)
+ ;
/* force state machines to be idle also when a signal occurred */
- so->tx.state = ISOTP_IDLE;
+ so->tx.state = ISOTP_SHUTDOWN;
so->rx.state = ISOTP_IDLE;
spin_lock(&isotp_notifier_lock);
--
2.39.2
From: Michal Sojka <michal.sojka(a)cvut.cz>
When using select()/poll()/epoll() with a non-blocking ISOTP socket to
wait for when non-blocking write is possible, a false EPOLLOUT event
is sometimes returned. This can happen at least after sending a
message which must be split to multiple CAN frames.
The reason is that isotp_sendmsg() returns -EAGAIN when tx.state is
not equal to ISOTP_IDLE and this behavior is not reflected in
datagram_poll(), which is used in isotp_ops.
This is fixed by introducing ISOTP-specific poll function, which
suppresses the EPOLLOUT events in that case.
v2: https://lore.kernel.org/all/20230302092812.320643-1-michal.sojka@cvut.cz
v1: https://lore.kernel.org/all/20230224010659.48420-1-michal.sojka@cvut.czhttps://lore.kernel.org/all/b53a04a2-ba1f-3858-84c1-d3eb3301ae15@hartkopp.n…
Signed-off-by: Michal Sojka <michal.sojka(a)cvut.cz>
Reported-by: Jakub Jira <jirajak2(a)fel.cvut.cz>
Tested-by: Oliver Hartkopp <socketcan(a)hartkopp.net>
Acked-by: Oliver Hartkopp <socketcan(a)hartkopp.net>
Fixes: e057dd3fc20f ("can: add ISO 15765-2:2016 transport protocol")
Link: https://lore.kernel.org/all/20230331125511.372783-1-michal.sojka@cvut.cz
Cc: stable(a)vger.kernel.org
Signed-off-by: Marc Kleine-Budde <mkl(a)pengutronix.de>
---
net/can/isotp.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/net/can/isotp.c b/net/can/isotp.c
index 47c2ebad10ed..281b7766c54e 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -1608,6 +1608,21 @@ static int isotp_init(struct sock *sk)
return 0;
}
+static __poll_t isotp_poll(struct file *file, struct socket *sock, poll_table *wait)
+{
+ struct sock *sk = sock->sk;
+ struct isotp_sock *so = isotp_sk(sk);
+
+ __poll_t mask = datagram_poll(file, sock, wait);
+ poll_wait(file, &so->wait, wait);
+
+ /* Check for false positives due to TX state */
+ if ((mask & EPOLLWRNORM) && (so->tx.state != ISOTP_IDLE))
+ mask &= ~(EPOLLOUT | EPOLLWRNORM);
+
+ return mask;
+}
+
static int isotp_sock_no_ioctlcmd(struct socket *sock, unsigned int cmd,
unsigned long arg)
{
@@ -1623,7 +1638,7 @@ static const struct proto_ops isotp_ops = {
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
.getname = isotp_getname,
- .poll = datagram_poll,
+ .poll = isotp_poll,
.ioctl = isotp_sock_no_ioctlcmd,
.gettstamp = sock_gettstamp,
.listen = sock_no_listen,
--
2.39.2
From: Oliver Hartkopp <socketcan(a)hartkopp.net>
isotp.c was still using sock_recv_timestamp() which does not provide
control messages to detect dropped PDUs in the receive path.
Fixes: e057dd3fc20f ("can: add ISO 15765-2:2016 transport protocol")
Signed-off-by: Oliver Hartkopp <socketcan(a)hartkopp.net>
Link: https://lore.kernel.org/all/20230330170248.62342-1-socketcan@hartkopp.net
Cc: stable(a)vger.kernel.org
Signed-off-by: Marc Kleine-Budde <mkl(a)pengutronix.de>
---
net/can/isotp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/can/isotp.c b/net/can/isotp.c
index 9bc344851704..47c2ebad10ed 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -1120,7 +1120,7 @@ static int isotp_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
if (ret < 0)
goto out_err;
- sock_recv_timestamp(msg, sk, skb);
+ sock_recv_cmsgs(msg, sk, skb);
if (msg->msg_name) {
__sockaddr_check_size(ISOTP_MIN_NAMELEN);
--
2.39.2
This is the start of the stable review cycle for the 4.14.312 release.
There are 66 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, 05 Apr 2023 14:03:18 +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.312-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.312-rc1
Harshit Mogalapalli <harshit.m.mogalapalli(a)oracle.com>
ca8210: Fix unsigned mac_len comparison with zero in ca8210_skb_tx()
Jamal Hadi Salim <jhs(a)mojatatu.com>
net: sched: cbq: dont intepret cls results when asked to drop
Ye Bin <yebin10(a)huawei.com>
ext4: fix kernel BUG in 'ext4_write_inline_data_end()'
Dan Carpenter <dan.carpenter(a)oracle.com>
usb: host: ohci-pxa27x: Fix and & vs | typo
Heiko Carstens <hca(a)linux.ibm.com>
s390/uaccess: add missing earlyclobber annotations to __clear_user()
Lucas Stach <l.stach(a)pengutronix.de>
drm/etnaviv: fix reference leak when mmaping imported buffer
Takashi Iwai <tiwai(a)suse.de>
ALSA: usb-audio: Fix regression on detection of Roland VS-100
Takashi Iwai <tiwai(a)suse.de>
ALSA: hda/conexant: Partial revert of a quirk for Lenovo
Johan Hovold <johan+linaro(a)kernel.org>
pinctrl: at91-pio4: fix domain name assignment
Juergen Gross <jgross(a)suse.com>
xen/netback: don't do grant copy across page boundary
David Disseldorp <ddiss(a)suse.de>
cifs: fix DFS traversal oops without CONFIG_CIFS_DFS_UPCALL
Jason A. Donenfeld <Jason(a)zx2c4.com>
Input: focaltech - use explicitly signed char type
Radoslaw Tyl <radoslawx.tyl(a)intel.com>
i40e: fix registers dump after run ethtool adapter self test
Ivan Orlov <ivan.orlov0322(a)gmail.com>
can: bcm: bcm_tx_setup(): fix KMSAN uninit-value in vfs_write
Tomas Henzl <thenzl(a)redhat.com>
scsi: megaraid_sas: Fix crash after a double completion
Wei Chen <harperchen1110(a)gmail.com>
fbdev: au1200fb: Fix potential divide by zero
Wei Chen <harperchen1110(a)gmail.com>
fbdev: lxfb: Fix potential divide by zero
Wei Chen <harperchen1110(a)gmail.com>
fbdev: intelfb: Fix potential divide by zero
Wei Chen <harperchen1110(a)gmail.com>
fbdev: nvidia: Fix potential divide by zero
Linus Torvalds <torvalds(a)linux-foundation.org>
sched_getaffinity: don't assume 'cpumask_size()' is fully initialized
Wei Chen <harperchen1110(a)gmail.com>
fbdev: tgafb: Fix potential divide by zero
Kuninori Morimoto <kuninori.morimoto.gx(a)renesas.com>
ALSA: hda/ca0132: fixup buffer overrun at tuning_ctl_set()
Kuninori Morimoto <kuninori.morimoto.gx(a)renesas.com>
ALSA: asihpi: check pao in control_message()
NeilBrown <neilb(a)suse.de>
md: avoid signed overflow in slot_store()
Jan Kara via Ocfs2-devel <ocfs2-devel(a)oss.oracle.com>
ocfs2: fix data corruption after failed write
Vincent Guittot <vincent.guittot(a)linaro.org>
sched/fair: Sanitize vruntime of entity being migrated
Zhang Qiao <zhangqiao22(a)huawei.com>
sched/fair: sanitize vruntime of entity being placed
Mikulas Patocka <mpatocka(a)redhat.com>
dm crypt: add cond_resched() to dmcrypt_write()
Jiasheng Jiang <jiasheng(a)iscas.ac.cn>
dm stats: check for and propagate alloc_percpu failure
Wei Chen <harperchen1110(a)gmail.com>
i2c: xgene-slimpro: Fix out-of-bounds bug in xgene_slimpro_i2c_xfer()
Ryusuke Konishi <konishi.ryusuke(a)gmail.com>
nilfs2: fix kernel-infoleak in nilfs_ioctl_wrap_copy()
Xu Yang <xu.yang_2(a)nxp.com>
usb: chipidea: core: fix possible concurrent when switch role
Xu Yang <xu.yang_2(a)nxp.com>
usb: chipdea: core: fix return -EINVAL if request role is the same with current role
Lin Ma <linma(a)zju.edu.cn>
igb: revert rtnl_lock() that causes deadlock
Alvin Šipraga <alsi(a)bang-olufsen.dk>
usb: gadget: u_audio: don't let userspace block driver unbind
Joel Selvaraj <joelselvaraj.oss(a)gmail.com>
scsi: core: Add BLIST_SKIP_VPD_PAGES for SKhynix H28U74301AMR
Al Viro <viro(a)zeniv.linux.org.uk>
sh: sanitize the flags on sigreturn
Enrico Sau <enrico.sau(a)gmail.com>
net: usb: qmi_wwan: add Telit 0x1080 composition
Enrico Sau <enrico.sau(a)gmail.com>
net: usb: cdc_mbim: avoid altsetting toggling for Telit FE990
Adrien Thierry <athierry(a)redhat.com>
scsi: ufs: core: Add soft dependency on governor_simpleondemand
Maurizio Lombardi <mlombard(a)redhat.com>
scsi: target: iscsi: Fix an error message in iscsi_check_key()
Michael Schmitz <schmitzmic(a)gmail.com>
m68k: Only force 030 bus error if PC not in exception table
Alexander Aring <aahringo(a)redhat.com>
ca8210: fix mac_len negative array access
Alexandre Ghiti <alex(a)ghiti.fr>
riscv: Bump COMMAND_LINE_SIZE value to 1024
Mario Limonciello <mario.limonciello(a)amd.com>
thunderbolt: Use const qualifier for `ring_interrupt_index`
Yaroslav Furman <yaro330(a)gmail.com>
uas: Add US_FL_NO_REPORT_OPCODES for JMicron JMS583Gen 2
Frank Crawford <frank(a)crawford.emu.id.au>
hwmon (it87): Fix voltage scaling for chips with 10.9mV ADCs
Zheng Wang <zyytlz.wz(a)163.com>
Bluetooth: btsdio: fix use after free bug in btsdio_remove due to unfinished work
Stephan Gerhold <stephan.gerhold(a)kernkonzept.com>
Bluetooth: btqcomsmd: Fix command timeout after setting BD address
Liang He <windhl(a)126.com>
net: mdio: thunder: Add missing fwnode_handle_put()
Roger Pau Monne <roger.pau(a)citrix.com>
hvc/xen: prevent concurrent accesses to the shared ring
Li Zetao <lizetao1(a)huawei.com>
atm: idt77252: fix kmemleak when rmmod idt77252
Maher Sanalla <msanalla(a)nvidia.com>
net/mlx5: Read the TC mapping of all priorities on ETS query
Daniel Borkmann <daniel(a)iogearbox.net>
bpf: Adjust insufficient default bpf_jit_limit
Geoff Levand <geoff(a)infradead.org>
net/ps3_gelic_net: Use dma_mapping_error
Geoff Levand <geoff(a)infradead.org>
net/ps3_gelic_net: Fix RX sk_buff length
Zheng Wang <zyytlz.wz(a)163.com>
net: qcom/emac: Fix use after free bug in emac_remove due to race condition
Zheng Wang <zyytlz.wz(a)163.com>
xirc2ps_cs: Fix use after free bug in xirc2ps_detach
Daniil Tatianin <d-tatianin(a)yandex-team.ru>
qed/qed_sriov: guard against NULL derefs from qed_iov_get_vf_info
Szymon Heidrich <szymon.heidrich(a)gmail.com>
net: usb: smsc95xx: Limit packet length to skb->len
Yu Kuai <yukuai3(a)huawei.com>
scsi: scsi_dh_alua: Fix memleak for 'qdata' in alua_activate()
Alexander Stein <alexander.stein(a)ew.tq-group.com>
i2c: imx-lpi2c: check only for enabled interrupt flags
Akihiko Odaki <akihiko.odaki(a)daynix.com>
igbvf: Regard vf reset nack as success
Gaosheng Cui <cuigaosheng1(a)huawei.com>
intel/igbvf: free irq on the error path in igbvf_request_msix()
Alexander Lobakin <aleksander.lobakin(a)intel.com>
iavf: fix inverted Rx hash condition leading to disabled hash
Zheng Wang <zyytlz.wz(a)163.com>
power: supply: da9150: Fix use after free bug in da9150_charger_remove due to race condition
-------------
Diffstat:
Makefile | 4 +-
arch/m68k/kernel/traps.c | 4 +-
arch/riscv/include/uapi/asm/setup.h | 8 ++++
arch/s390/lib/uaccess.c | 2 +-
arch/sh/include/asm/processor_32.h | 1 +
arch/sh/kernel/signal_32.c | 3 ++
drivers/atm/idt77252.c | 11 +++++
drivers/bluetooth/btqcomsmd.c | 17 ++++++-
drivers/bluetooth/btsdio.c | 1 +
drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 10 +++-
drivers/hwmon/it87.c | 4 +-
drivers/i2c/busses/i2c-imx-lpi2c.c | 4 ++
drivers/i2c/busses/i2c-xgene-slimpro.c | 3 ++
drivers/input/mouse/focaltech.c | 8 ++--
drivers/md/dm-crypt.c | 1 +
drivers/md/dm-stats.c | 7 ++-
drivers/md/dm-stats.h | 2 +-
drivers/md/dm.c | 4 +-
drivers/md/md.c | 3 ++
drivers/net/ethernet/intel/i40e/i40e_diag.c | 11 +++--
drivers/net/ethernet/intel/i40e/i40e_diag.h | 2 +-
drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 2 +-
drivers/net/ethernet/intel/igb/igb_main.c | 2 -
drivers/net/ethernet/intel/igbvf/netdev.c | 8 +++-
drivers/net/ethernet/intel/igbvf/vf.c | 13 ++++--
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 6 ++-
drivers/net/ethernet/qlogic/qed/qed_sriov.c | 5 +-
drivers/net/ethernet/qualcomm/emac/emac.c | 6 +++
drivers/net/ethernet/toshiba/ps3_gelic_net.c | 41 ++++++++--------
drivers/net/ethernet/toshiba/ps3_gelic_net.h | 5 +-
drivers/net/ethernet/xircom/xirc2ps_cs.c | 5 ++
drivers/net/ieee802154/ca8210.c | 5 +-
drivers/net/phy/mdio-thunder.c | 1 +
drivers/net/usb/cdc_mbim.c | 5 ++
drivers/net/usb/qmi_wwan.c | 1 +
drivers/net/usb/smsc95xx.c | 6 +++
drivers/net/xen-netback/common.h | 2 +-
drivers/net/xen-netback/netback.c | 25 +++++++++-
drivers/pinctrl/pinctrl-at91-pio4.c | 1 -
drivers/power/supply/da9150-charger.c | 1 +
drivers/scsi/device_handler/scsi_dh_alua.c | 6 ++-
drivers/scsi/megaraid/megaraid_sas_fusion.c | 4 +-
drivers/scsi/scsi_devinfo.c | 1 +
drivers/scsi/ufs/ufshcd.c | 1 +
drivers/target/iscsi/iscsi_target_parameters.c | 12 +++--
drivers/thunderbolt/nhi.c | 2 +-
drivers/tty/hvc/hvc_xen.c | 19 +++++++-
drivers/usb/chipidea/ci.h | 2 +
drivers/usb/chipidea/core.c | 11 ++++-
drivers/usb/chipidea/otg.c | 5 +-
drivers/usb/gadget/function/u_audio.c | 2 +-
drivers/usb/host/ohci-pxa27x.c | 2 +-
drivers/usb/storage/unusual_uas.h | 7 +++
drivers/video/fbdev/au1200fb.c | 3 ++
drivers/video/fbdev/geode/lxfb_core.c | 3 ++
drivers/video/fbdev/intelfb/intelfbdrv.c | 3 ++
drivers/video/fbdev/nvidia/nvidia.c | 2 +
drivers/video/fbdev/tgafb.c | 3 ++
fs/cifs/cifsfs.h | 5 +-
fs/ext4/inode.c | 3 +-
fs/nilfs2/ioctl.c | 2 +-
fs/ocfs2/aops.c | 18 +++++++-
kernel/bpf/core.c | 2 +-
kernel/compat.c | 2 +-
kernel/sched/core.c | 7 ++-
kernel/sched/fair.c | 54 ++++++++++++++++++++--
net/can/bcm.c | 16 ++++---
net/sched/sch_cbq.c | 4 +-
sound/pci/asihpi/hpi6205.c | 2 +-
sound/pci/hda/patch_ca0132.c | 4 +-
sound/pci/hda/patch_conexant.c | 6 ++-
sound/usb/format.c | 8 +++-
72 files changed, 370 insertions(+), 101 deletions(-)
From: "Steven Rostedt (Google)" <rostedt(a)goodmis.org>
The kernel command line ftrace_boot_snapshot by itself is supposed to
trigger a snapshot at the end of boot up of the main top level trace
buffer. A ftrace_boot_snapshot=foo will do the same for an instance called
foo that was created by trace_instance=foo,...
The logic was broken where if ftrace_boot_snapshot was by itself, it would
trigger a snapshot for all instances that had tracing enabled, regardless
if it asked for a snapshot or not.
When a snapshot is requested for a buffer, the buffer's
tr->allocated_snapshot is set to true. Use that to know if a trace buffer
wants a snapshot at boot up or not.
Since the top level buffer is part of the ftrace_trace_arrays list,
there's no reason to treat it differently than the other buffers. Just
iterate the list if ftrace_boot_snapshot was specified.
Cc: stable(a)vger.kernel.org
Fixes: 9c1c251d670bc ("tracing: Allow boot instances to have snapshot buffers")
Signed-off-by: Steven Rostedt (Google) <rostedt(a)goodmis.org>
---
kernel/trace/trace.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index ed1d1093f5e9..8ae51f1dea8e 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -10395,16 +10395,15 @@ void __init ftrace_boot_snapshot(void)
{
struct trace_array *tr;
- if (snapshot_at_boot) {
- tracing_snapshot();
- internal_trace_puts("** Boot snapshot taken **\n");
- }
+ if (!snapshot_at_boot)
+ return;
list_for_each_entry(tr, &ftrace_trace_arrays, list) {
- if (tr == &global_trace)
+ if (!tr->allocated_snapshot)
continue;
- trace_array_puts(tr, "** Boot snapshot taken **\n");
+
tracing_snapshot_instance(tr);
+ trace_array_puts(tr, "** Boot snapshot taken **\n");
}
}
--
2.39.2
From: "Steven Rostedt (Google)" <rostedt(a)goodmis.org>
The kernel command line ftrace_boot_snapshot by itself is supposed to
trigger a snapshot at the end of boot up of the main top level trace
buffer. A ftrace_boot_snapshot=foo will do the same for an instance called
foo that was created by trace_instance=foo,...
The logic was broken where if ftrace_boot_snapshot was by itself, it would
trigger a snapshot for all instances that had tracing enabled, regardless
if it asked for a snapshot or not.
When a snapshot is requested for a buffer, the buffer's
tr->allocated_snapshot is set to true. Use that to know if a trace buffer
wants a snapshot at boot up or not.
Since the top level buffer is part of the ftrace_trace_arrays list,
there's no reason to treat it differently than the other buffers. Just
iterate the list if ftrace_boot_snapshot was specified.
Cc: stable(a)vger.kernel.org
Fixes: 9c1c251d670bc ("tracing: Allow boot instances to have snapshot buffers")
Signed-off-by: Steven Rostedt (Google) <rostedt(a)goodmis.org>
---
Changes since v1: https://lkml.kernel.org/r/20230404230308.501833715@goodmis.org
- Protect use of tr->allocated_snapshot around #ifdef TRACER_MAX_TRACE
kernel/trace/trace.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 93740a9370c6..36a6037823cd 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -10394,19 +10394,20 @@ __init static int tracer_alloc_buffers(void)
void __init ftrace_boot_snapshot(void)
{
+#ifdef CONFIG_TRACER_MAX_TRACE
struct trace_array *tr;
- if (snapshot_at_boot) {
- tracing_snapshot();
- internal_trace_puts("** Boot snapshot taken **\n");
- }
+ if (!snapshot_at_boot)
+ return;
list_for_each_entry(tr, &ftrace_trace_arrays, list) {
- if (tr == &global_trace)
+ if (!tr->allocated_snapshot)
continue;
- trace_array_puts(tr, "** Boot snapshot taken **\n");
+
tracing_snapshot_instance(tr);
+ trace_array_puts(tr, "** Boot snapshot taken **\n");
}
+#endif
}
void __init early_trace_init(void)
--
2.39.2