5.10.5-rc1 review
Subsystems (9)
Greg Kroah-Hartman
maintainercover 5.10.5-rc1 review
This is the start of the stable review cycle for the 5.10.5 release. There are 63 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, 06 Jan 2021 15:56:52 +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/v5.x/stable-review/patch-5.10.5-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.10.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 5.10.5-rc1
Dan Williams <[email protected]>
device-dax: Fix range release
Chunguang Xu <[email protected]>
ext4: avoid s_mb_prefetch to be zero in individual scenarios
Hyeongseok Kim <[email protected]>
dm verity: skip verity work if I/O error when system is shutting down
Takashi Iwai <[email protected]>
ALSA: pcm: Clear the full allocated memory at hw_params
Pavel Begunkov <[email protected]>
io_uring: remove racy overflow list fast checks
Heiko Carstens <[email protected]>
s390: always clear kernel stack backchain before calling functions
Thomas Gleixner <[email protected]>
tick/sched: Remove bogus boot "safety" check
Jake Wang <[email protected]>
drm/amd/display: updated wm table for Renoir
Jeff Layton <[email protected]>
ceph: fix inode refcount leak when ceph_fill_inode on non-I_NEW inode fails
Trond Myklebust <[email protected]>
NFSv4.2: Don't error when exiting early on a READ_PLUS buffer overflow
Gabriel Krisman Bertazi <[email protected]>
um: ubd: Submit all data segments atomically
Christopher Obbard <[email protected]>
um: random: Register random as hwrng-core device
Zhang Qilong <[email protected]>
watchdog: rti-wdt: fix reference leak in rti_wdt_probe
Eric Biggers <[email protected]>
fs/namespace.c: WARN if mnt_count has become negative
Nicholas Piggin <[email protected]>
powerpc/64: irq replay remove decrementer overflow check
Jessica Yu <[email protected]>
module: delay kobject uevent until after module init call
Daeho Jeong <[email protected]>
f2fs: fix race of pending_pages in decompression
Jaegeuk Kim <[email protected]>
f2fs: avoid race condition for shrinker count
Trond Myklebust <[email protected]>
NFSv4: Fix a pNFS layout related use-after-free race when freeing the inode
Qinglang Miao <[email protected]>
i3c master: fix missing destroy_workqueue() on error in i3c_master_register
Qinglang Miao <[email protected]>
powerpc: sysdev: add missing iounmap() on error in mpic_msgr_probe()
Zheng Liang <[email protected]>
rtc: pl031: fix resource leak in pl031_probe
Jan Kara <[email protected]>
quota: Don't overflow quota file offsets
Miroslav Benes <[email protected]>
module: set MODULE_STATE_GOING state when a module fails to load
Dinghao Liu <[email protected]>
rtc: sun6i: Fix memleak in sun6i_rtc_clk_init
Xiaoguang Wang <[email protected]>
io_uring: check kthread stopped flag when sq thread is unparked
Boqun Feng <[email protected]>
fcntl: Fix potential deadlock in send_sig{io, urg}()
Theodore Ts'o <[email protected]>
ext4: check for invalid block size early when mounting a file system
Randy Dunlap <[email protected]>
bfs: don't use WARNING: string when it's just info.
Takashi Iwai <[email protected]>
ALSA: rawmidi: Access runtime->avail always in spinlock
Takashi Iwai <[email protected]>
ALSA: seq: Use bool for snd_seq_queue internal flags
Chao Yu <[email protected]>
f2fs: fix shift-out-of-bounds in sanity_check_raw_super()
Mauro Carvalho Chehab <[email protected]>
media: gp8psk: initialize stats at power control logic
Anant Thazhemadam <[email protected]>
misc: vmw_vmci: fix kernel info-leak by initializing dbells in vmci_ctx_get_chkpt_doorbells()
Rustam Kovhaev <[email protected]>
reiserfs: add check for an invalid ih_entry_count
Daniel Vetter <[email protected]>
fbcon: Disable accelerated scrolling
Anant Thazhemadam <[email protected]>
Bluetooth: hci_h5: close serdev device and free hu in h5_close
Randy Dunlap <[email protected]>
scsi: cxgb4i: Fix TLS dependency
Randy Dunlap <[email protected]>
zlib: move EXPORT_SYMBOL() and MODULE_LICENSE() out of dfltcc_syms.c
Qinglang Miao <[email protected]>
cgroup: Fix memory leak when parsing multiple source parameters
Arnaldo Carvalho de Melo <[email protected]>
tools headers UAPI: Sync linux/const.h with the kernel headers
Petr Vorel <[email protected]>
uapi: move constants from <linux/kernel.h> to <linux/const.h>
Pavel Begunkov <[email protected]>
kernel/io_uring: cancel io_uring before task works
Pavel Begunkov <[email protected]>
io_uring: fix io_sqe_files_unregister() hangs
Pavel Begunkov <[email protected]>
io_uring: add a helper for setting a ref node
Jens Axboe <[email protected]>
io_uring: use bottom half safe lock for fixed file data
Jens Axboe <[email protected]>
io_uring: don't assume mm is constant across submits
Ilya Leoshkevich <[email protected]>
lib/zlib: fix inflating zlib streams on s390
Baoquan He <[email protected]>
mm: memmap defer init doesn't work as expected
Mike Kravetz <[email protected]>
mm/hugetlb: fix deadlock in hugetlb_cow error path
Bart Van Assche <[email protected]>
scsi: block: Fix a race in the runtime power management code
Viresh Kumar <[email protected]>
opp: Call the missing clk_put() on error
Quanyang Wang <[email protected]>
opp: fix memory leak in _allocate_opp_table
Serge Semin <[email protected]>
spi: dw-bt1: Fix undefined devm_mux_control_get symbol
Jamie Iles <[email protected]>
jffs2: Fix NULL pointer dereference in rp_size fs option parsing
lizhe <[email protected]>
jffs2: Allow setting rp_size to zero during remounting
Pavel Begunkov <[email protected]>
io_uring: close a small race gap for files cancel
Rodrigo Siqueira <[email protected]>
drm/amd/display: Add get_dig_frontend implementation for DCEx
Kevin Vigor <[email protected]>
md/raid10: initialize r10_bio->read_slot before use.
Michal Kubecek <[email protected]>
ethtool: fix string set id check
Ivan Vecera <[email protected]>
ethtool: fix error paths in ethnl_set_channels()
Paolo Abeni <[email protected]>
mptcp: fix security context on server socket
Davide Caratti <[email protected]>
net/sched: sch_taprio: reset child qdiscs before freeing them
-------------
Diffstat:
Documentation/gpu/todo.rst | 18 ++ Makefile | 4 +- arch/ia64/mm/init.c | 4 +- arch/powerpc/kernel/irq.c | 53 +----- arch/powerpc/kernel/time.c | 9 +- arch/powerpc/platforms/powernv/opal.c | 2 +- arch/powerpc/sysdev/mpic_msgr.c | 2 +- arch/s390/kernel/entry.S | 12 +- arch/um/drivers/random.c | 101 +++-------- arch/um/drivers/ubd_kern.c | 191 +++++++++++++-------- block/blk-pm.c | 15 +- drivers/bluetooth/hci_h5.c | 8 +- drivers/char/hw_random/Kconfig | 16 +- drivers/dax/bus.c | 44 +++-- .../drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 12 +- .../gpu/drm/amd/display/dc/dce/dce_link_encoder.c | 44 ++++- .../gpu/drm/amd/display/dc/dce/dce_link_encoder.h | 2 + drivers/i3c/master.c | 5 +- drivers/md/dm-verity-target.c | 12 +- drivers/md/raid10.c | 3 +- drivers/media/usb/dvb-usb/gp8psk.c | 2 +- drivers/misc/vmw_vmci/vmci_context.c | 2 +- drivers/opp/core.c | 9 +- drivers/rtc/rtc-pl031.c | 6 +- drivers/rtc/rtc-sun6i.c | 8 +- drivers/scsi/cxgbi/cxgb4i/Kconfig | 1 + drivers/spi/Kconfig | 3 +- drivers/video/fbdev/core/fbcon.c | 45 +---- drivers/watchdog/rti_wdt.c | 4 +- fs/bfs/inode.c | 2 +- fs/ceph/inode.c | 2 + fs/ext4/mballoc.c | 9 +- fs/ext4/super.c | 40 ++--- fs/f2fs/checkpoint.c | 2 +- fs/f2fs/compress.c | 2 - fs/f2fs/data.c | 58 +++++-- fs/f2fs/debug.c | 11 +- fs/f2fs/f2fs.h | 11 +- fs/f2fs/node.c | 29 ++-- fs/f2fs/node.h | 4 +- fs/f2fs/shrinker.c | 4 +- fs/f2fs/super.c | 9 +- fs/fcntl.c | 10 +- fs/file.c | 2 - fs/io_uring.c | 91 ++++++---- fs/jffs2/jffs2_fs_sb.h | 1 + fs/jffs2/super.c | 17 +- fs/namespace.c | 9 +- fs/nfs/nfs42xdr.c | 36 ++-- fs/nfs/nfs4super.c | 2 +- fs/nfs/pnfs.c | 33 +++- fs/nfs/pnfs.h | 5 + fs/pnode.h | 2 +- fs/quota/quota_tree.c | 8 +- fs/reiserfs/stree.c | 6 + include/linux/mm.h | 5 +- include/uapi/linux/const.h | 5 + include/uapi/linux/ethtool.h | 2 +- include/uapi/linux/kernel.h | 9 +- include/uapi/linux/lightnvm.h | 2 +- include/uapi/linux/mroute6.h | 2 +- include/uapi/linux/netfilter/x_tables.h | 2 +- include/uapi/linux/netlink.h | 2 +- include/uapi/linux/sysctl.h | 2 +- kernel/cgroup/cgroup-v1.c | 2 + kernel/exit.c | 2 + kernel/module.c | 6 +- kernel/time/tick-sched.c | 7 - lib/zlib_dfltcc/Makefile | 2 +- lib/zlib_dfltcc/dfltcc.c | 6 +- lib/zlib_dfltcc/dfltcc_deflate.c | 3 + lib/zlib_dfltcc/dfltcc_inflate.c | 4 +- lib/zlib_dfltcc/dfltcc_syms.c | 17 -- mm/hugetlb.c | 22 ++- mm/memory_hotplug.c | 2 +- mm/page_alloc.c | 8 +- net/ethtool/channels.c | 6 +- net/ethtool/strset.c | 2 +- net/mptcp/protocol.c | 2 + net/sched/sch_taprio.c | 17 +- sound/core/pcm_native.c | 9 +- sound/core/rawmidi.c | 49 ++++-- sound/core/seq/seq_queue.h | 8 +- tools/include/uapi/linux/const.h | 5 + 84 files changed, 713 insertions(+), 539 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/63 net/sched: sch_taprio: reset child qdiscs before freeing them
From: Davide Caratti <[email protected]>
[ Upstream commit 44d4775ca51805b376a8db5b34f650434a08e556 ]
syzkaller shows that packets can still be dequeued while taprio_destroy() is running. Let sch_taprio use the reset() function to cancel the advance timer and drop all skbs from the child qdiscs.
--- net/sched/sch_taprio.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
net/sched/sch_taprio.c +16 -1
@@ -1596,6 +1596,21 @@ free_sched:return err; } +static void taprio_reset (struct Qdisc *sch) +{ +struct taprio_sched *q =qdisc_priv (sch); +struct net_device *dev =qdisc_dev (sch); +int i; + +hrtimer_cancel (&q->advance_timer); +if (q->qdiscs) { +for (i =0 ; i < dev->num_tx_queues && q->qdiscs[i]; i++) +qdisc_reset (q->qdiscs[i]); + } + sch->qstats.backlog =0 ; + sch->q.qlen =0 ; +} +static void taprio_destroy (struct Qdisc *sch) {struct taprio_sched *q =qdisc_priv (sch);
@@ -1606,7 +1621,6 @@ static void taprio_destroy(struct Qdisclist_del (&q->taprio_list);spin_unlock (&taprio_list_lock); -hrtimer_cancel (&q->advance_timer);taprio_disable_offload (dev, q,NULL );
@@ -1953,6 +1967,7 @@ static struct Qdisc_ops taprio_qdisc_ops .init = taprio_init, .change = taprio_change, .destroy = taprio_destroy, + .reset = taprio_reset, .peek = taprio_peek, .dequeue = taprio_dequeue, .enqueue = taprio_enqueue,
Sasha Levin
maintainerRe: [PATCH 5.10 01/63] net/sched: sch_taprio: reset child qdiscs before freeing them
Quoted 8 lines · Greg Kroah-Hartman
From: Davide Caratti <[email protected]>
[ Upstream commit
44d4775ca51805b376a8db5b34f650434a08e556]syzkaller shows that packets can still be dequeued while
taprio_destroy()is running. Letsch_tapriouse thereset()function to cancel the advance timer and drop all skbs from the child qdiscs.
Quoted 8 lines
Fixes 5a781ccbd19e ("tc: Add support for configuring the taprio scheduler")Reported-by [email protected]Signed-off-by Davide Caratti <[email protected]>Link https://lore.kernel.org/r/63b6d79b0e830ebb0283e020db4df3cdfdfb2b94.1608142843.git.dcaratti@redhat.com open hereSigned-off-by Jakub Kicinski <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>
I noticed that there's a fix for this patch going through netdev (but not yet in Linus's tree). The fix reads to me like it fixes a missed corner case by this patch rather than this patch being incorrect, so I'll leave this patch in. If anyone disagrees please speak up :)
Signature · 2 lines
Thanks, Sasha
Re: [PATCH 5.10 01/63] net/sched: sch_taprio: reset child qdiscs before freeing them
Quoted 18 lines · On Mon, 4 Jan 2021 17:58:27 -0500 Sasha Levin wrote:
Quoted 8 lines · Greg Kroah-Hartman
From: Davide Caratti <[email protected]>
[ Upstream commit
44d4775ca51805b376a8db5b34f650434a08e556]syzkaller shows that packets can still be dequeued while
taprio_destroy()is running. Letsch_tapriouse thereset()function to cancel the advance timer and drop all skbs from the child qdiscs.Quoted 8 lines
Fixes 5a781ccbd19e ("tc: Add support for configuring the taprio scheduler")Reported-by [email protected]Signed-off-by Davide Caratti <[email protected]>Link https://lore.kernel.org/r/63b6d79b0e830ebb0283e020db4df3cdfdfb2b94.1608142843.git.dcaratti@redhat.com open hereSigned-off-by Jakub Kicinski <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>
Quoted 4 lines
I noticed that there's a fix for this patch going through netdev (but not yet in Linus's tree). The fix reads to me like it fixes a missed corner case by this patch rather than this patch being incorrect, so I'll leave this patch in. If anyone disagrees please speak up :)
Right, the other fix is independent, it came up in review and we decided to address it separately.
Greg Kroah-Hartman
maintainerPATCH 2/63 mptcp: fix security context on server socket
In reply to Greg Kroah-HartmanFrom: Paolo Abeni <[email protected]>
[ Upstream commit 0c14846032f2c0a3b63234e1fc2759f4155b6067 ]
Currently MPTCP is not propagating the security context from the ingress request socket to newly created msk at clone time.
Address the issue invoking the missing security helper.
--- net/mptcp/protocol.c | 2 ++ 1 file changed, 2 insertions(+)
net/mptcp/protocol.c +2 -0
@@ -2081,6 +2081,8 @@ struct sock *mptcp_sk_clone(const structsock_reset_flag (nsk,SOCK_RCU_FREE );/* will be fully established after successful MPC subflow creation */ inet_sk_state_store (nsk,TCP_SYN_RECV ); + +security_inet_csk_clone (nsk, req);bh_unlock_sock (nsk);/* keep a single reference */
Greg Kroah-Hartman
maintainerPATCH 3/63 ethtool: fix error paths in ethnl_set_channels()
In reply to Greg Kroah-HartmanFrom: Ivan Vecera <[email protected]>
[ Upstream commit ef72cd3c5ce168829c6684ecb2cae047d3493690 ]
Fix two error paths in ethnl_set_channels() to avoid lock-up caused but unreleased RTNL.
--- net/ethtool/channels.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/ethtool/channels.c +4 -2
@@ -194,8 +194,9 @@ int ethnl_set_channels(struct sk_buff *sif (netif_is_rxfh_configured (dev) && !ethtool_get_max_rxfh_channel (dev, &max_rx_in_use) && (channels.combined_count + channels.rx_count) <= max_rx_in_use) { + ret = -EINVAL ;GENL_SET_ERR_MSG (info,"requested channel counts are too low for existing indirection table settings" ); -return -EINVAL ; + goto out_ops; }/* Disabling channels, query zero-copy AF_XDP sockets */
@@ -203,8 +204,9 @@ int ethnl_set_channels(struct sk_buff *smin (channels.rx_count, channels.tx_count);for (i = from_channel; i < old_total; i++)if (xsk_get_pool_from_qid (dev, i)) { + ret = -EINVAL ;GENL_SET_ERR_MSG (info,"requested channel counts are too low for existing zerocopy AF_XDP sockets" ); -return -EINVAL ; + goto out_ops; } ret = dev->ethtool_ops->set_channels (dev, &channels);
Greg Kroah-Hartman
maintainerPATCH 4/63 ethtool: fix string set id check
In reply to Greg Kroah-HartmanFrom: Michal Kubecek <[email protected]>
[ Upstream commit efb796f5571f030743e1d9c662cdebdad724f8c5 ]
Syzbot reported a shift of a u32 by more than 31 in strset_parse_request() which is undefined behavior. This is caused by range check of string set id using variable ret (which is always 0 at this point) instead of id (string set id from request).
--- net/ethtool/strset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ethtool/strset.c +1 -1
@@ -182,7 +182,7 @@ static int strset_parse_request(struct e ret =strset_get_id (attr, &id, extack);if (ret <0 )return ret; -if (ret >=ETH_SS_COUNT ) { +if (id >=ETH_SS_COUNT ) {NL_SET_ERR_MSG_ATTR (extack, attr,"unknown string set id" );return -EOPNOTSUPP ;
Greg Kroah-Hartman
maintainerPATCH 5/63 md/raid10: initialize r10_bio->read_slot before use.
In reply to Greg Kroah-HartmanFrom: Kevin Vigor <[email protected]>
commit 93decc563637c4288380912eac0eb42fb246cc04 upstream.
In __make_request() a new r10bio is allocated and passed to raid10_read_request(). The read_slot member of the bio is not initialized, and the raid10_read_request() uses it to index an array. This leads to occasional panics.
Fix by initializing the field to invalid value and checking for valid value in raid10_read_request().
--- drivers/md/raid10.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/md/raid10.c +2 -1
@@ -1128,7 +1128,7 @@ static void raid10_read_request(struct mstruct md_rdev *err_rdev =NULL ;gfp_t gfp =GFP_NOIO ; -if (r10_bio->devs[slot].rdev) { +if (slot >=0 && r10_bio->devs[slot].rdev) {/* * This is an error retry, but we cannot * safely dereference the rdev in the r10_bio,
@@ -1493,6 +1493,7 @@ static void __make_request(struct mddev r10_bio->mddev = mddev; r10_bio->sector = bio->bi_iter.bi_sector; r10_bio->state =0 ; + r10_bio->read_slot =-1 ;memset (r10_bio->devs,0 ,sizeof (r10_bio->devs[0 ]) * conf->copies);if (bio_data_dir (bio) ==READ )
Greg Kroah-Hartman
maintainerPATCH 6/63 drm/amd/display: Add get_dig_frontend implementation for DCEx
In reply to Greg Kroah-HartmanFrom: Rodrigo Siqueira <[email protected]>
commit 6bdeff12a96c9a5da95c8d11fefd145eb165e32a upstream.
Some old ASICs might not implement/require get_dig_frontend helper; in this scenario, we can have a NULL pointer exception when we try to call it inside vbios disable operation. For example, this situation might happen when using Polaris12 with an eDP panel. This commit avoids this situation by adding a specific get_dig_frontend implementation for DCEx.
--- drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | 44 +++++++++++++++++- drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h | 2 2 files changed, 44 insertions(+), 2 deletions(-)
drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +42 -2
@@ -119,7 +119,8 @@ static const struct link_encoder_funcs d .disable_hpd = dce110_link_encoder_disable_hpd, .is_dig_enabled = dce110_is_dig_enabled, .destroy = dce110_link_encoder_destroy, - .get_max_link_cap = dce110_link_encoder_get_max_link_cap + .get_max_link_cap = dce110_link_encoder_get_max_link_cap, + .get_dig_frontend = dce110_get_dig_frontend, }; static enum bp_result link_transmitter_control(
@@ -235,6 +236,44 @@ static void set_link_training_complete( } +unsigned int dce110_get_dig_frontend (struct link_encoder *enc) +{ +struct dce110_link_encoder *enc110 =TO_DCE110_LINK_ENC (enc); +u32 value; +enum engine_id result; + +REG_GET (DIG_BE_CNTL ,DIG_FE_SOURCE_SELECT , &value); + +switch (value) { +case DCE110_DIG_FE_SOURCE_SELECT_DIGA : + result =ENGINE_ID_DIGA ; +break ; +case DCE110_DIG_FE_SOURCE_SELECT_DIGB : + result =ENGINE_ID_DIGB ; +break ; +case DCE110_DIG_FE_SOURCE_SELECT_DIGC : + result =ENGINE_ID_DIGC ; +break ; +case DCE110_DIG_FE_SOURCE_SELECT_DIGD : + result =ENGINE_ID_DIGD ; +break ; +case DCE110_DIG_FE_SOURCE_SELECT_DIGE : + result =ENGINE_ID_DIGE ; +break ; +case DCE110_DIG_FE_SOURCE_SELECT_DIGF : + result =ENGINE_ID_DIGF ; +break ; +case DCE110_DIG_FE_SOURCE_SELECT_DIGG : + result =ENGINE_ID_DIGG ; +break ; +default : +// invalid source select DIG + result =ENGINE_ID_UNKNOWN ; + } + +return result; +} +void dce110_link_encoder_set_dp_phy_pattern_training_pattern (struct link_encoder *enc,uint32_t index)
@@ -1665,7 +1704,8 @@ static const struct link_encoder_funcs d .disable_hpd = dce110_link_encoder_disable_hpd, .is_dig_enabled = dce110_is_dig_enabled, .destroy = dce110_link_encoder_destroy, - .get_max_link_cap = dce110_link_encoder_get_max_link_cap + .get_max_link_cap = dce110_link_encoder_get_max_link_cap, + .get_dig_frontend = dce110_get_dig_frontend }; void dce60_link_encoder_construct(
drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h +2 -0
@@ -295,6 +295,8 @@ void dce110_link_encoder_connect_dig_be_enum engine_id engine, bool connect); +unsigned int dce110_get_dig_frontend (struct link_encoder *enc); +void dce110_link_encoder_set_dp_phy_pattern_training_pattern (struct link_encoder *enc,uint32_t index);
Greg Kroah-Hartman
maintainerPATCH 7/63 io_uring: close a small race gap for files cancel
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
commit dfea9fce29fda6f2f91161677e0e0d9b671bc099 upstream.
The purpose of io_uring_cancel_files() is to wait for all requests matching ->files to go/be cancelled. We should first drop files of a request in io_req_drop_files() and only then make it undiscoverable for io_uring_cancel_files.
First drop, then delete from list. It's ok to leave req->id->files dangling, because it's not dereferenced by cancellation code, only compared against. It would potentially go to sleep and be awaken by following in io_req_drop_files() wake_up().
--- fs/io_uring.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/io_uring.c +4 -4
@@ -5861,15 +5861,15 @@ static void io_req_drop_files(struct io_struct io_ring_ctx *ctx = req->ctx;unsigned long flags; +put_files_struct (req->work.identity->files); +put_nsproxy (req->work.identity->nsproxy);spin_lock_irqsave (&ctx->inflight_lock, flags);list_del (&req->inflight_entry); -if (waitqueue_active (&ctx->inflight_wait)) -wake_up (&ctx->inflight_wait);spin_unlock_irqrestore (&ctx->inflight_lock, flags); req->flags &= ~REQ_F_INFLIGHT ; -put_files_struct (req->work.identity->files); -put_nsproxy (req->work.identity->nsproxy); req->work.flags &= ~IO_WQ_WORK_FILES ; +if (waitqueue_active (&ctx->inflight_wait)) +wake_up (&ctx->inflight_wait); }static void __io_clean_op (struct io_kiocb *req)
Greg Kroah-Hartman
maintainerPATCH 8/63 jffs2: Allow setting rp_size to zero during remounting
In reply to Greg Kroah-HartmanFrom: lizhe <[email protected]>
[ Upstream commit cd3ed3c73ac671ff6b0230ccb72b8300292d3643 ]
Set rp_size to zero will be ignore during remounting.
The method to identify whether we input a remounting option of rp_size is to check if the rp_size input is zero. It can not work well if we pass "rp_size=0".
This patch add a bool variable "set_rp_size" to fix this problem.
--- fs/jffs2/jffs2_fs_sb.h | 1 + fs/jffs2/super.c | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-)
fs/jffs2/jffs2_fs_sb.h +1 -0
@@ -38,6 +38,7 @@ struct jffs2_mount_opts {* users. This is implemented simply by means of not allowing the * latter users to write to the file system if the amount if the * available space is less then 'rp_size'. */ +bool set_rp_size;unsigned int rp_size; };
fs/jffs2/super.c +5 -2
@@ -88,7 +88,7 @@ static int jffs2_show_options(struct seq_file *s, struct dentry *root)if (opts->override_compr)seq_printf (s,",compr=%s" ,jffs2_compr_name (opts->compr)); -if (opts->rp_size) +if (opts->set_rp_size)seq_printf (s,",rp_size=%u" , opts->rp_size /1024 );return 0 ;
@@ -206,6 +206,7 @@ static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param)if (opt > c->mtd->size)return invalf (fc,"jffs2: Too large reserve pool specified, max is %llu KB" , c->mtd->size /1024 ); + c->mount_opts.set_rp_size = true; c->mount_opts.rp_size = opt;break ;default :
@@ -225,8 +226,10 @@ static inline void jffs2_update_mount_opts(struct fs_context *fc) c->mount_opts.override_compr = new_c->mount_opts.override_compr; c->mount_opts.compr = new_c->mount_opts.compr; } -if (new_c->mount_opts.rp_size) +if (new_c->mount_opts.set_rp_size) { + c->mount_opts.set_rp_size = new_c->mount_opts.set_rp_size; c->mount_opts.rp_size = new_c->mount_opts.rp_size; + }mutex_unlock (&c->alloc_sem); }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 9/63 jffs2: Fix NULL pointer dereference in rp_size fs option parsing
In reply to Greg Kroah-HartmanFrom: Jamie Iles <[email protected]>
[ Upstream commit a61df3c413e49b0042f9caf774c58512d1cc71b7 ]
syzkaller found the following JFFS2 splat:
Unable to handle kernel paging request at virtual address dfffa00000000001
Mem abort info:
ESR = 0x96000004
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
[dfffa00000000001] address between user and kernel address ranges
Internal error: Oops: 96000004 [#1] SMP
Dumping ftrace buffer:
(ftrace buffer empty)
Modules linked in:
CPU: 0 PID: 12745 Comm: syz-executor.5 Tainted: G S 5.9.0-rc8+ #98
Hardware name: linux,dummy-virt (DT)
pstate: 20400005 (nzCv daif +PAN -UAO BTYPE=--)
pc : jffs2_parse_param+0x138/0x308 fs/jffs2/super.c:206
lr : jffs2_parse_param+0x108/0x308 fs/jffs2/super.c:205
sp : ffff000022a57910
x29: ffff000022a57910 x28: 0000000000000000
x27: ffff000057634008 x26: 000000000000d800
x25: 000000000000d800 x24: ffff0000271a9000
x23: ffffa0001adb5dc0 x22: ffff000023fdcf00
x21: 1fffe0000454af2c x20: ffff000024cc9400
x19: 0000000000000000 x18: 0000000000000000
x17: 0000000000000000 x16: ffffa000102dbdd0
x15: 0000000000000000 x14: ffffa000109e44bc
x13: ffffa00010a3a26c x12: ffff80000476e0b3
x11: 1fffe0000476e0b2 x10: ffff80000476e0b2
x9 : ffffa00010a3ad60 x8 : ffff000023b70593
x7 : 0000000000000003 x6 : 00000000f1f1f1f1
x5 : ffff000023fdcf00 x4 : 0000000000000002
x3 : ffffa00010000000 x2 : 0000000000000001
x1 : dfffa00000000000 x0 : 0000000000000008
Call trace:
jffs2_parse_param+0x138/0x308 fs/jffs2/super.c:206
vfs_parse_fs_param+0x234/0x4e8 fs/fs_context.c:117
vfs_parse_fs_string+0xe8/0x148 fs/fs_context.c:161
generic_parse_monolithic+0x17c/0x208 fs/fs_context.c:201
parse_monolithic_mount_data+0x7c/0xa8 fs/fs_context.c:649
do_new_mount fs/namespace.c:2871 [inline]
path_mount+0x548/0x1da8 fs/namespace.c:3192
do_mount+0x124/0x138 fs/namespace.c:3205
__do_sys_mount fs/namespace.c:3413 [inline]
__se_sys_mount fs/namespace.c:3390 [inline]
__arm64_sys_mount+0x164/0x238 fs/namespace.c:3390
__invoke_syscall arch/arm64/kernel/syscall.c:36 [inline]
invoke_syscall arch/arm64/kernel/syscall.c:48 [inline]
el0_svc_common.constprop.0+0x15c/0x598 arch/arm64/kernel/syscall.c:149
do_el0_svc+0x60/0x150 arch/arm64/kernel/syscall.c:195
el0_svc+0x34/0xb0 arch/arm64/kernel/entry-common.c:226
el0_sync_handler+0xc8/0x5b4 arch/arm64/kernel/entry-common.c:236
el0_sync+0x15c/0x180 arch/arm64/kernel/entry.S:663
Code: d2d40001 f2fbffe1 91002260 d343fc02 (38e16841)
---[ end trace 4edf690313deda44 ]---This is because since ec10a24f10c8, the option parsing happens before fill_super and so the MTD device isn't associated with the filesystem. Defer the size check until there is a valid association.
--- fs/jffs2/super.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
fs/jffs2/super.c +5 -5
@@ -202,12 +202,8 @@ static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param)case Opt_rp_size:if (result.uint_32 >UINT_MAX /1024 )return invalf (fc,"jffs2: rp_size unrepresentable" ); - opt = result.uint_32 *1024 ; -if (opt > c->mtd->size) -return invalf (fc,"jffs2: Too large reserve pool specified, max is %llu KB" , - c->mtd->size /1024 ); + c->mount_opts.rp_size = result.uint_32 *1024 ; c->mount_opts.set_rp_size = true; - c->mount_opts.rp_size = opt;break ;default :return -EINVAL ;
@@ -269,6 +265,10 @@ static int jffs2_fill_super(struct super_block *sb, struct fs_context *fc) c->mtd = sb->s_mtd; c->os_priv = sb; +if (c->mount_opts.rp_size > c->mtd->size) +return invalf (fc,"jffs2: Too large reserve pool specified, max is %llu KB" , + c->mtd->size /1024 ); +/* Initialize JFFS2 superblock locks, the further initialization will * be done later */ mutex_init (&c->alloc_sem);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 10/63 spi: dw-bt1: Fix undefined devm_mux_control_get symbol
In reply to Greg Kroah-HartmanFrom: Serge Semin <[email protected]>
commit 7218838109fef61cdec988ff728e902d434c9cc5 upstream.
I mistakenly added the select attributes to the SPI_DW_BT1_DIRMAP config instead of having them defined in SPI_DW_BT1. If the kernel doesn't have the MULTIPLEXER and MUX_MMIO configs manually enabled and the SPI_DW_BT1_DIRMAP config hasn't been selected, Baikal-T1 SPI device will always fail to be probed by the driver. Fix that and the error reported by the test robot:
Quoted 3 lines
Quoted 3 lines
ld.lld: error: undefined symbol:
devm_mux_control_getQuoted 2 lines
referenced by
spi-dw-bt1.cspi/spi-dw-bt1.o:(dw_spi_bt1_sys_init) in archivedrivers/built-in.a
by moving the MULTIPLEXER/MUX_MMIO configs selection to the SPI_DW_BT1 config.
--- drivers/spi/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/spi/Kconfig +1 -2
@@ -256,6 +256,7 @@ config SPI_DW_BT1 tristate "Baikal-T1 SPI driver for DW SPI core" depends on MIPS_BAIKAL_T1 || COMPILE_TEST select MULTIPLEXER + select MUX_MMIO help Baikal-T1 SoC is equipped with three DW APB SSI-based MMIO SPI controllers. Two of them are pretty much normal: with IRQ, DMA,
@@ -269,8 +270,6 @@ config SPI_DW_BT1 config SPI_DW_BT1_DIRMAP bool "Directly mapped Baikal-T1 Boot SPI flash support" depends on SPI_DW_BT1 - select MULTIPLEXER - select MUX_MMIO help Directly mapped SPI flash memory is an interface specific to the Baikal-T1 System Boot Controller. It is a 16MB MMIO region, which
Greg Kroah-Hartman
maintainerPATCH 11/63 opp: fix memory leak in _allocate_opp_table
In reply to Greg Kroah-HartmanFrom: Quanyang Wang <[email protected]>
commit 976509bb310b913d30577f15b58bdd30effb0542 upstream.
In function _allocate_opp_table, opp_dev is allocated and referenced by opp_table via _add_opp_dev. But in the case that the subsequent calls return -EPROBE_DEFER, it will jump to err label and opp_table will be freed. Then opp_dev becomes an unreferenced object to cause memory leak. So let's call _remove_opp_dev to do the cleanup.
This fixes the following kmemleak report:
unreferenced object 0xffff000801524a00 (size 128):
comm "swapper/0", pid 1, jiffies 4294892465 (age 84.616s) hex dump (first 32 bytes):
40 00 56 01 08 00 ff ff 40 00 56 01 08 00 ff ff @[email protected]..... b8 52 77 7f 08 00 ff ff 00 3c 4c 00 08 00 ff ff .Rw......<L..... backtrace: [<00000000b1289fb1>] kmemleak_alloc+0x30/0x40 [<0000000056da48f0>] kmem_cache_alloc+0x3d4/0x588 [<00000000a84b3b0e>] _add_opp_dev+0x2c/0x88 [<0000000062a380cd>] _add_opp_table_indexed+0x124/0x268 [<000000008b4c8f1f>] dev_pm_opp_of_add_table+0x20/0x1d8 [<00000000e5316798>] dev_pm_opp_of_cpumask_add_table+0x48/0xf0 [<00000000db0a8ec2>] dt_cpufreq_probe+0x20c/0x448 [<0000000030a3a26c>] platform_probe+0x68/0xd8 [<00000000c618e78d>] really_probe+0xd0/0x3a0 [<00000000642e856f>] driver_probe_device+0x58/0xb8 [<00000000f10f5307>] device_driver_attach+0x74/0x80 [<0000000004f254b8>] __driver_attach+0x58/0xe0 [<0000000009d5d19e>] bus_for_each_dev+0x70/0xc8 [<0000000000d22e1c>] driver_attach+0x24/0x30 [<0000000001d4e952>] bus_add_driver+0x14c/0x1f0 [<0000000089928aaa>] driver_register+0x64/0x120
--- drivers/opp/core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/opp/core.c +4 -2
@@ -1102,7 +1102,7 @@ static struct opp_table *_allocate_opp_tif (IS_ERR (opp_table->clk)) { ret =PTR_ERR (opp_table->clk);if (ret == -EPROBE_DEFER ) - goto err; + goto remove_opp_dev;dev_dbg (dev,"%s: Couldn't find clock: %d\n" , __func__, ret); }
@@ -1111,7 +1111,7 @@ static struct opp_table *_allocate_opp_t ret =dev_pm_opp_of_find_icc_paths (dev, opp_table);if (ret) {if (ret == -EPROBE_DEFER ) - goto err; + goto remove_opp_dev;dev_warn (dev,"%s: Error finding interconnect paths: %d\n" , __func__, ret);
@@ -1125,6 +1125,8 @@ static struct opp_table *_allocate_opp_tlist_add (&opp_table->node, &opp_tables);return opp_table; +remove_opp_dev: +_remove_opp_dev (opp_dev, opp_table); err:kfree (opp_table);return ERR_PTR (ret);
Greg Kroah-Hartman
maintainerPATCH 12/63 opp: Call the missing clk_put() on error
In reply to Greg Kroah-HartmanFrom: Viresh Kumar <[email protected]>
commit 0e1d9ca1766f5d95fb881f57b6c4a1ffa63d4648 upstream.
Fix the clock reference counting by calling the missing clk_put() in the error path.
--- drivers/opp/core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/opp/core.c +4 -1
@@ -1111,7 +1111,7 @@ static struct opp_table *_allocate_opp_t ret =dev_pm_opp_of_find_icc_paths (dev, opp_table);if (ret) {if (ret == -EPROBE_DEFER ) - goto remove_opp_dev; + goto put_clk;dev_warn (dev,"%s: Error finding interconnect paths: %d\n" , __func__, ret);
@@ -1125,6 +1125,9 @@ static struct opp_table *_allocate_opp_tlist_add (&opp_table->node, &opp_tables);return opp_table; +put_clk: +if (!IS_ERR (opp_table->clk)) +clk_put (opp_table->clk); remove_opp_dev:_remove_opp_dev (opp_dev, opp_table); err:
Greg Kroah-Hartman
maintainerPATCH 13/63 scsi: block: Fix a race in the runtime power management code
In reply to Greg Kroah-HartmanFrom: Bart Van Assche <[email protected]>
commit fa4d0f1992a96f6d7c988ef423e3127e613f6ac9 upstream.
With the current implementation the following race can happen:
* blk_pre_runtime_suspend() calls blk_freeze_queue_start() and blk_mq_unfreeze_queue().
* blk_queue_enter() calls blk_queue_pm_only() and that function returns true.
* blk_queue_enter() calls blk_pm_request_resume() and that function does not call pm_request_resume() because the queue runtime status is RPM_ACTIVE.
* blk_pre_runtime_suspend() changes the queue status into RPM_SUSPENDING.
Fix this race by changing the queue runtime status into RPM_SUSPENDING before switching q_usage_counter to atomic mode.
--- block/blk-pm.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
block/blk-pm.c +9 -6
@@ -67,6 +67,10 @@ int blk_pre_runtime_suspend(struct requeWARN_ON_ONCE (q->rpm_status !=RPM_ACTIVE ); +spin_lock_irq (&q->queue_lock); + q->rpm_status =RPM_SUSPENDING ; +spin_unlock_irq (&q->queue_lock); +/* * Increase the pm_only counter before checking whether any * non-PM blk_queue_enter() calls are in progress to avoid that any
@@ -89,15 +93,14 @@ int blk_pre_runtime_suspend(struct reque/* Switch q_usage_counter back to per-cpu mode. */ blk_mq_unfreeze_queue (q); -spin_lock_irq (&q->queue_lock); -if (ret <0 ) +if (ret <0 ) { +spin_lock_irq (&q->queue_lock); + q->rpm_status =RPM_ACTIVE ;pm_runtime_mark_last_busy (q->dev); -else - q->rpm_status =RPM_SUSPENDING ; -spin_unlock_irq (&q->queue_lock); +spin_unlock_irq (&q->queue_lock); -if (ret)blk_clear_pm_only (q); + }return ret; }
Greg Kroah-Hartman
maintainerPATCH 14/63 mm/hugetlb: fix deadlock in hugetlb_cow error path
In reply to Greg Kroah-HartmanFrom: Mike Kravetz <[email protected]>
commit e7dd91c456a8cdbcd7066997d15e36d14276a949 upstream.
syzbot reported the deadlock here [1]. The issue is in hugetlb cow error handling when there are not enough huge pages for the faulting task which took the original reservation. It is possible that other (child) tasks could have consumed pages associated with the reservation. In this case, we want the task which took the original reservation to succeed. So, we unmap any associated pages in children so that they can be used by the faulting task that owns the reservation.
The unmapping code needs to hold i_mmap_rwsem in write mode. However, due to commit c0d0381ade79 ("hugetlbfs: use i_mmap_rwsem for more pmd sharing synchronization") we are already holding i_mmap_rwsem in read mode when hugetlb_cow is called.
Technically, i_mmap_rwsem does not need to be held in read mode for COW mappings as they can not share pmd's. Modifying the fault code to not take i_mmap_rwsem in read mode for COW (and other non-sharable) mappings is too involved for a stable fix.
Instead, we simply drop the hugetlb_fault_mutex and i_mmap_rwsem before unmapping. This is OK as it is technically not needed. They are reacquired after unmapping as expected by calling code. Since this is done in an uncommon error path, the overhead of dropping and reacquiring mutexes is acceptable.
While making changes, remove redundant BUG_ON after unmap_ref_private.
[1] https://lkml.kernel.org/r/[email protected]
--- mm/hugetlb.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-)
mm/hugetlb.c +21 -1
@@ -4106,10 +4106,30 @@ retry_avoidcopy:* may get SIGKILLed if it later faults. */ if (outside_reserve) { +struct address_space *mapping = vma->vm_file->f_mapping; +pgoff_t idx; +u32 hash; +put_page (old_page);BUG_ON (huge_pte_none (pte)); +/* +* Drop hugetlb_fault_mutex and i_mmap_rwsem before +* unmapping. unmapping needs to hold i_mmap_rwsem +* in write mode. Dropping i_mmap_rwsem in read mode +* here is OK as COW mappings do not interact with +* PMD sharing. +* +* Reacquire both after unmap operation. +*/ + idx =vma_hugecache_offset (h, vma, haddr); + hash =hugetlb_fault_mutex_hash (mapping, idx); +mutex_unlock (&hugetlb_fault_mutex_table[hash]); +i_mmap_unlock_read (mapping); +unmap_ref_private (mm, vma, old_page, haddr); -BUG_ON (huge_pte_none (pte)); + +i_mmap_lock_read (mapping); +mutex_lock (&hugetlb_fault_mutex_table[hash]);spin_lock (ptl); ptep =huge_pte_offset (mm, haddr,huge_page_size (h)); if (likely(ptep &&
Greg Kroah-Hartman
maintainerPATCH 15/63 mm: memmap defer init doesnt work as expected
In reply to Greg Kroah-HartmanFrom: Baoquan He <[email protected]>
commit dc2da7b45ffe954a0090f5d0310ed7b0b37d2bd2 upstream.
VMware observed a performance regression during memmap init on their platform, and bisected to commit 73a6e474cb376 ("mm: memmap_init:
iterate over memblock regions rather that check each PFN") causing it.
Before the commit:
[0.033176] Normal zone: 1445888 pages used for memmap [0.033176] Normal zone: 89391104 pages, LIFO batch:63 [0.035851] ACPI: PM-Timer IO Port: 0x448
With commit
[0.026874] Normal zone: 1445888 pages used for memmap [0.026875] Normal zone: 89391104 pages, LIFO batch:63 [2.028450] ACPI: PM-Timer IO Port: 0x448
The root cause is the current memmap defer init doesn't work as expected.
Before, memmap_init_zone() was used to do memmap init of one whole zone, to initialize all low zones of one numa node, but defer memmap init of the last zone in that numa node. However, since commit 73a6e474cb376, function memmap_init() is adapted to iterater over memblock regions inside one zone, then call memmap_init_zone() to do memmap init for each region.
E.g, on VMware's system, the memory layout is as below, there are two memory regions in node 2. The current code will mistakenly initialize the whole 1st region [mem 0xab00000000-0xfcffffffff], then do memmap defer to iniatialize only one memmory section on the 2nd region [mem 0x10000000000-0x1033fffffff]. In fact, we only expect to see that there's only one memory section's memmap initialized. That's why more time is costed at the time.
[ 0.008842] ACPI: SRAT: Node 0 PXM 0 [mem 0x00000000-0x0009ffff] [ 0.008842] ACPI: SRAT: Node 0 PXM 0 [mem 0x00100000-0xbfffffff] [ 0.008843] ACPI: SRAT: Node 0 PXM 0 [mem 0x100000000-0x55ffffffff] [ 0.008844] ACPI: SRAT: Node 1 PXM 1 [mem 0x5600000000-0xaaffffffff] [ 0.008844] ACPI: SRAT: Node 2 PXM 2 [mem 0xab00000000-0xfcffffffff] [ 0.008845] ACPI: SRAT: Node 2 PXM 2 [mem 0x10000000000-0x1033fffffff]
Now, let's add a parameter 'zone_end_pfn' to memmap_init_zone() to pass down the real zone end pfn so that defer_init() can use it to judge whether defer need be taken in zone wide.
--- arch/ia64/mm/init.c | 4 ++-- include/linux/mm.h | 5 +++-- mm/memory_hotplug.c | 2 +- mm/page_alloc.c | 8 +++++--- 4 files changed, 11 insertions(+), 8 deletions(-)
arch/ia64/mm/init.c +2 -2
@@ -536,7 +536,7 @@ virtual_memmap_init(u64 start, u64 end,if (map_start < map_end)memmap_init_zone ((unsigned long )(map_end - map_start), - args->nid, args->zone,page_to_pfn (map_start), + args->nid, args->zone,page_to_pfn (map_start),page_to_pfn (map_end),MEMINIT_EARLY ,NULL ,MIGRATE_MOVABLE );return 0 ; }
@@ -546,7 +546,7 @@ memmap_init (unsigned long size, int nid unsigned long start_pfn) {if (!vmem_map) { -memmap_init_zone (size, nid, zone, start_pfn, +memmap_init_zone (size, nid, zone, start_pfn, start_pfn + size,MEMINIT_EARLY ,NULL ,MIGRATE_MOVABLE ); }else {struct page *start;
include/linux/mm.h +3 -2
@@ -2439,8 +2439,9 @@ extern int __meminit __early_pfn_to_nid(#endif extern void set_dma_reserve (unsigned long new_dma_reserve); -extern void memmap_init_zone (unsigned long ,int ,unsigned long ,unsigned long , -enum meminit_context ,struct vmem_altmap *,int migratetype); +extern void memmap_init_zone (unsigned long ,int ,unsigned long , +unsigned long ,unsigned long ,enum meminit_context , +struct vmem_altmap *,int migratetype);extern void setup_per_zone_wmarks (void );extern int __meminit init_per_zone_wmark_min (void );extern void mem_init (void );
mm/memory_hotplug.c +1 -1
@@ -714,7 +714,7 @@ void __ref move_pfn_range_to_zone(struct* expects the zone spans the pfn range. All the pages in the range * are reserved so nobody should be touching them so we should be safe */ -memmap_init_zone (nr_pages, nid,zone_idx (zone), start_pfn, +memmap_init_zone (nr_pages, nid,zone_idx (zone), start_pfn,0 ,MEMINIT_HOTPLUG , altmap, migratetype);set_zone_contiguous (zone);
mm/page_alloc.c +5 -3
@@ -448,6 +448,8 @@ defer_init(int nid, unsigned long pfn, uif (end_pfn <pgdat_end_pfn (NODE_DATA (nid)))return false; +if (NODE_DATA (nid)->first_deferred_pfn !=ULONG_MAX ) +return true;/* * We start only with one section of pages, more pages are added as * needed until the rest of deferred pages are initialized.
@@ -6050,7 +6052,7 @@ overlap_memmap_init(unsigned long zone,* zone stats (e.g., nr_isolate_pageblock) are touched. */ void __meminit memmap_init_zone (unsigned long size,int nid,unsigned long zone, -unsigned long start_pfn, +unsigned long start_pfn,unsigned long zone_end_pfn,enum meminit_context context,struct vmem_altmap *altmap,int migratetype) {
@@ -6086,7 +6088,7 @@ void __meminit memmap_init_zone(unsignedif (context ==MEMINIT_EARLY ) {if (overlap_memmap_init (zone, &pfn))continue ; -if (defer_init (nid, pfn, end_pfn)) +if (defer_init (nid, pfn, zone_end_pfn))break ; }
@@ -6200,7 +6202,7 @@ void __meminit __weak memmap_init(unsignif (end_pfn > start_pfn) { size = end_pfn - start_pfn; -memmap_init_zone (size, nid, zone, start_pfn, +memmap_init_zone (size, nid, zone, start_pfn, range_end_pfn,MEMINIT_EARLY ,NULL ,MIGRATE_MOVABLE ); } }
Greg Kroah-Hartman
maintainerPATCH 16/63 lib/zlib: fix inflating zlib streams on s390
In reply to Greg Kroah-HartmanFrom: Ilya Leoshkevich <[email protected]>
commit f0bb29e8c4076444d32df00c8d32e169ceecf283 upstream.
Decompressing zlib streams on s390 fails with "incorrect data check" error.
Userspace zlib checks inflate_state.flags in order to byteswap checksums only for zlib streams, and s390 hardware inflate code, which was ported from there, tries to match this behavior. At the same time, kernel zlib does not use inflate_state.flags, so it contains essentially random values. For many use cases either zlib stream is zeroed out or checksum is not used, so this problem is masked, but at least SquashFS is still affected.
Fix by always passing a checksum to and from the hardware as is, which matches zlib_inflate()'s expectations.
--- lib/zlib_dfltcc/dfltcc_inflate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
lib/zlib_dfltcc/dfltcc_inflate.c +2 -2
@@ -125,7 +125,7 @@ dfltcc_inflate_action dfltcc_inflate( param->ho = (state->write - state->whave) & ((1 <<HB_BITS ) -1 );if (param->hl) param->nt =0 ;/* Honor history for the first block */ - param->cv = state->flags ?REVERSE (state->check) : state->check; + param->cv = state->check;/* Inflate */ do {
@@ -138,7 +138,7 @@ dfltcc_inflate_action dfltcc_inflate( state->bits = param->sbb; state->whave = param->hl; state->write = (param->ho + param->hl) & ((1 <<HB_BITS ) -1 ); - state->check = state->flags ?REVERSE (param->cv) : param->cv; + state->check = param->cv;if (cc ==DFLTCC_CC_OP2_CORRUPT && param->oesc !=0 ) {/* Report an error if stream is corrupted */ state->mode =BAD ;
Greg Kroah-Hartman
maintainerPATCH 17/63 io_uring: dont assume mm is constant across submits
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit 77788775c7132a8d93c6930ab1bd84fc743c7cb7 upstream.
If we COW the identity, we assume that ->mm never changes. But this isn't true of multiple processes end up sharing the ring. Hence treat id->mm like like any other process compontent when it comes to the identity mapping. This is pretty trivial, just moving the existing grab into io_grab_identity(), and including a check for the match.
--- fs/io_uring.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
fs/io_uring.c +7 -7
@@ -1369,6 +1369,13 @@ static bool io_grab_identity(struct io_kspin_unlock_irq (&ctx->inflight_lock); req->work.flags |=IO_WQ_WORK_FILES ; } +if (!(req->work.flags &IO_WQ_WORK_MM ) && + (def->work_flags &IO_WQ_WORK_MM )) { +if (id->mm != current->mm) +return false; +mmgrab (id->mm); + req->work.flags |=IO_WQ_WORK_MM ; + }return true; }
@@ -1393,13 +1400,6 @@ static void io_prep_async_work(struct io req->work.flags |=IO_WQ_WORK_UNBOUND ; } -/* ->mm can never change on us */ -if (!(req->work.flags &IO_WQ_WORK_MM ) && - (def->work_flags &IO_WQ_WORK_MM )) { -mmgrab (id->mm); - req->work.flags |=IO_WQ_WORK_MM ; - } -/* if we fail grabbing identity, we must COW, regrab, and retry */ if (io_grab_identity (req))return ;
Greg Kroah-Hartman
maintainerPATCH 18/63 io_uring: use bottom half safe lock for fixed file data
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit ac0648a56c1ff66c1cbf735075ad33a26cbc50de upstream.
io_file_data_ref_zero() can be invoked from soft-irq from the RCU core, hence we need to ensure that the file_data lock is bottom half safe. Use the _bh() variants when grabbing this lock.
--- fs/io_uring.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
fs/io_uring.c +8 -8
@@ -7000,9 +7000,9 @@ static int io_sqe_files_unregister(strucif (!data)return -ENXIO ; -spin_lock (&data->lock); +spin_lock_bh (&data->lock); ref_node = data->node; -spin_unlock (&data->lock); +spin_unlock_bh (&data->lock);if (ref_node)percpu_ref_kill (&ref_node->refs);
@@ -7385,7 +7385,7 @@ static void io_file_data_ref_zero(struct data = ref_node->file_data; ctx = data->ctx; -spin_lock (&data->lock); +spin_lock_bh (&data->lock); ref_node->done = true;while (!list_empty (&data->ref_list)) {
@@ -7397,7 +7397,7 @@ static void io_file_data_ref_zero(structlist_del (&ref_node->node); first_add |=llist_add (&ref_node->llist, &ctx->file_put_llist); } -spin_unlock (&data->lock); +spin_unlock_bh (&data->lock);if (percpu_ref_is_dying (&data->refs)) delay =0 ;
@@ -7520,9 +7520,9 @@ static int io_sqe_files_register(struct } file_data->node = ref_node; -spin_lock (&file_data->lock); +spin_lock_bh (&file_data->lock);list_add_tail (&ref_node->node, &file_data->ref_list); -spin_unlock (&file_data->lock); +spin_unlock_bh (&file_data->lock);percpu_ref_get (&file_data->refs);return ret; out_fput:
@@ -7679,10 +7679,10 @@ static int __io_sqe_files_update(structif (needs_switch) {percpu_ref_kill (&data->node->refs); -spin_lock (&data->lock); +spin_lock_bh (&data->lock);list_add_tail (&ref_node->node, &data->ref_list); data->node = ref_node; -spin_unlock (&data->lock); +spin_unlock_bh (&data->lock);percpu_ref_get (&ctx->file_data->refs); }else destroy_fixed_file_ref_node (ref_node);
Greg Kroah-Hartman
maintainerPATCH 19/63 io_uring: add a helper for setting a ref node
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
commit 1642b4450d20e31439c80c28256c8eee08684698 upstream.
Setting a new reference node to a file data is not trivial, don't repeat it, add and use a helper.
--- fs/io_uring.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
fs/io_uring.c +12 -10
@@ -6991,6 +6991,16 @@ static void io_file_ref_kill(struct perccomplete (&data->done); } +static void io_sqe_files_set_node (struct fixed_file_data *file_data, +struct fixed_file_ref_node *ref_node) +{ +spin_lock_bh (&file_data->lock); + file_data->node = ref_node; +list_add_tail (&ref_node->node, &file_data->ref_list); +spin_unlock_bh (&file_data->lock); +percpu_ref_get (&file_data->refs); +} +static int io_sqe_files_unregister (struct io_ring_ctx *ctx) {struct fixed_file_data *data = ctx->file_data;
@@ -7519,11 +7529,7 @@ static int io_sqe_files_register(structreturn PTR_ERR (ref_node); } - file_data->node = ref_node; -spin_lock_bh (&file_data->lock); -list_add_tail (&ref_node->node, &file_data->ref_list); -spin_unlock_bh (&file_data->lock); -percpu_ref_get (&file_data->refs); +io_sqe_files_set_node (file_data, ref_node);return ret; out_fput:for (i =0 ; i < ctx->nr_user_files; i++) {
@@ -7679,11 +7685,7 @@ static int __io_sqe_files_update(structif (needs_switch) {percpu_ref_kill (&data->node->refs); -spin_lock_bh (&data->lock); -list_add_tail (&ref_node->node, &data->ref_list); - data->node = ref_node; -spin_unlock_bh (&data->lock); -percpu_ref_get (&ctx->file_data->refs); +io_sqe_files_set_node (data, ref_node); }else destroy_fixed_file_ref_node (ref_node);
Greg Kroah-Hartman
maintainerPATCH 20/63 io_uring: fix io_sqe_files_unregister() hangs
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
commit 1ffc54220c444774b7f09e6d2121e732f8e19b94 upstream.
io_sqe_files_unregister() uninterruptibly waits for enqueued ref nodes, however requests keeping them may never complete, e.g. because of some userspace dependency. Make sure it's interruptible otherwise it would hang forever.
--- fs/io_uring.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
fs/io_uring.c +22 -2
@@ -941,6 +941,10 @@ enum io_mem_account { ACCT_PINNED, }; +static void destroy_fixed_file_ref_node (struct fixed_file_ref_node *ref_node); +static struct fixed_file_ref_node *alloc_fixed_file_ref_node ( +struct io_ring_ctx *ctx); +static void __io_complete_rw (struct io_kiocb *req,long res,long res2,struct io_comp_state *cs);static void io_cqring_fill_event (struct io_kiocb *req,long res);
@@ -7004,11 +7008,15 @@ static void io_sqe_files_set_node(structstatic int io_sqe_files_unregister (struct io_ring_ctx *ctx) {struct fixed_file_data *data = ctx->file_data; -struct fixed_file_ref_node *ref_node =NULL ; +struct fixed_file_ref_node *backup_node, *ref_node =NULL ;unsigned nr_tables, i; +int ret;if (!data)return -ENXIO ; + backup_node =alloc_fixed_file_ref_node (ctx); +if (!backup_node) +return -ENOMEM ;spin_lock_bh (&data->lock); ref_node = data->node;
@@ -7020,7 +7028,18 @@ static int io_sqe_files_unregister(struc/* wait for all refs nodes to complete */ flush_delayed_work (&ctx->file_put_work); -wait_for_completion (&data->done); +do { + ret =wait_for_completion_interruptible (&data->done); +if (!ret) +break ; + ret =io_run_task_work_sig (); +if (ret <0 ) { +percpu_ref_resurrect (&data->refs); +reinit_completion (&data->done); +io_sqe_files_set_node (data, backup_node); +return ret; + } + }while (1 );__io_sqe_files_unregister (ctx); nr_tables =DIV_ROUND_UP (ctx->nr_user_files,IORING_MAX_FILES_TABLE );
@@ -7031,6 +7050,7 @@ static int io_sqe_files_unregister(struckfree (data); ctx->file_data =NULL ; ctx->nr_user_files =0 ; +destroy_fixed_file_ref_node (backup_node);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 21/63 kernel/io_uring: cancel io_uring before task works
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
commit b1b6b5a30dce872f500dc43f067cba8e7f86fc7d upstream.
For cancelling io_uring requests it needs either to be able to run currently enqueued task_works or having it shut down by that moment. Otherwise io_uring_cancel_files() may be waiting for requests that won't ever complete.
Go with the first way and do cancellations before setting PF_EXITING and so before putting the task_work infrastructure into a transition state where task_work_run() would better not be called.
--- fs/file.c | 2 -- kernel/exit.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-)
fs/file.c +0 -2
@@ -21,7 +21,6 @@#include <linux/rcupdate.h> #include <linux/close_range.h> #include <net/sock.h> -#include <linux/io_uring.h> unsigned int sysctl_nr_open__read_mostly =1024 *1024 ;unsigned int sysctl_nr_open_min =BITS_PER_LONG ;
@@ -453,7 +452,6 @@ void exit_files(struct task_struct *tsk)struct files_struct * files = tsk->files;if (files) { -io_uring_files_cancel (files);task_lock (tsk); tsk->files =NULL ;task_unlock (tsk);
kernel/exit.c +2 -0
@@ -63,6 +63,7 @@#include <linux/random.h> #include <linux/rcuwait.h> #include <linux/compat.h> +#include <linux/io_uring.h> #include <linux/uaccess.h> #include <asm/unistd.h>
@@ -762,6 +763,7 @@ void __noreturn do_exit(long code)schedule (); } +io_uring_files_cancel (tsk->files);exit_signals (tsk);/* sets PF_EXITING */ /* sync mm's RSS info before statistics gathering */
Re: [PATCH 5.10 21/63] kernel/io_uring: cancel io_uring before task works
Quoted 8 lines · Greg Kroah-Hartman
From: Pavel Begunkov <[email protected]>
commit
b1b6b5a30dce872f500dc43f067cba8e7f86fc7dupstream.For cancelling
io_uringrequests it needs either to be able to run currently enqueuedtask_worksor having it shut down by that moment. Otherwiseio_uring_cancel_files()may be waiting for requests that won't ever complete.
Greg, can you drop it from stable for now? I'll backport it later when related problems are sorted.
Quoted 53 lines
Go with the first way and do cancellations before setting
PF_EXITINGand so before putting thetask_workinfrastructure into a transition state wheretask_work_run()would better not be called.Cc [email protected] # 5.5+Signed-off-by Pavel Begunkov <[email protected]>Signed-off-by Jens Axboe <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- fs/file.c | 2 -- kernel/exit.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-)fs/file.c +0
-2@@ -21,7 +21,6 @@#include <linux/rcupdate.h> #include <linux/close_range.h> #include <net/sock.h> -#include <linux/io_uring.h> unsigned int sysctl_nr_open__read_mostly =1024 *1024 ;unsigned int sysctl_nr_open_min =BITS_PER_LONG ;@@ -453,7 +452,6 @@ void exit_files(struct task_struct *tsk)struct files_struct * files = tsk->files;if (files) { -io_uring_files_cancel (files);task_lock (tsk); tsk->files =NULL ;task_unlock (tsk);kernel/exit.c +2
-0@@ -63,6 +63,7 @@#include <linux/random.h> #include <linux/rcuwait.h> #include <linux/compat.h> +#include <linux/io_uring.h> #include <linux/uaccess.h> #include <asm/unistd.h> @@ -762,6 +763,7 @@ void __noreturn do_exit(long code)schedule (); } +io_uring_files_cancel (tsk->files);exit_signals (tsk);/* sets PF_EXITING */ /* sync mm's RSS info before statistics gathering */
Signature · 1 line
Pavel Begunkov
Sasha Levin
maintainerRe: [PATCH 5.10 21/63] kernel/io_uring: cancel io_uring before task works
Quoted 5 lines · Pavel Begunkov
Quoted 4 lines · Greg Kroah-Hartman
From: Pavel Begunkov <[email protected]>
commit
b1b6b5a30dce872f500dc43f067cba8e7f86fc7dupstream.
Quoted 7 lines
Quoted 4 lines
For cancelling
io_uringrequests it needs either to be able to run currently enqueuedtask_worksor having it shut down by that moment. Otherwiseio_uring_cancel_files()may be waiting for requests that won't ever complete.Greg, can you drop it from stable for now? I'll backport it later when related problems are sorted.
I've dropped it, let us know when it's good to go back in.
Signature · 2 lines
Thanks, Sasha
Greg Kroah-Hartman
maintainerPATCH 22/63 uapi: move constants from <linux/kernel.h> to <linux/const.h>
In reply to Greg Kroah-HartmanFrom: Petr Vorel <[email protected]>
commit a85cbe6159ffc973e5702f70a3bd5185f8f3c38d upstream.
and include <linux/const.h> in UAPI headers instead of <linux/kernel.h>.
The reason is to avoid indirect <linux/sysinfo.h> include when using some network headers: <linux/netlink.h> or others -> <linux/kernel.h> -> <linux/sysinfo.h>.
This indirect include causes on MUSL redefinition of struct sysinfo when included both <sys/sysinfo.h> and some of UAPI headers:
In file included from x86_64-buildroot-linux-musl/sysroot/usr/include/linux/kernel.h:5,
from x86_64-buildroot-linux-musl/sysroot/usr/include/linux/netlink.h:5,
from ../include/tst_netlink.h:14,
from tst_crypto.c:13:
x86_64-buildroot-linux-musl/sysroot/usr/include/linux/sysinfo.h:8:8: error: redefinition of `struct sysinfo'
struct sysinfo {
^~~~~~~
In file included from ../include/tst_safe_macros.h:15,
from ../include/tst_test.h:93,
from tst_crypto.c:11:
x86_64-buildroot-linux-musl/sysroot/usr/include/sys/sysinfo.h:10:8: note: originally defined here--- include/uapi/linux/const.h | 5 +++++ include/uapi/linux/ethtool.h | 2 +- include/uapi/linux/kernel.h | 9 +-------- include/uapi/linux/lightnvm.h | 2 +- include/uapi/linux/mroute6.h | 2 +- include/uapi/linux/netfilter/x_tables.h | 2 +- include/uapi/linux/netlink.h | 2 +- include/uapi/linux/sysctl.h | 2 +- 8 files changed, 12 insertions(+), 14 deletions(-)
include/uapi/linux/const.h +5 -0
@@ -28,4 +28,9 @@#define _BITUL (x) (_UL(1) << (x))#define _BITULL (x) (_ULL(1) << (x)) +#define __ALIGN_KERNEL (x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) +#define __ALIGN_KERNEL_MASK (x, mask) (((x) + (mask)) & ~(mask)) + +#define __KERNEL_DIV_ROUND_UP (n, d) (((n) + (d) - 1) / (d)) +#endif /* _UAPI_LINUX_CONST_H */
include/uapi/linux/ethtool.h +1 -1
@@ -14,7 +14,7 @@#ifndef _UAPI_LINUX_ETHTOOL_H#define _UAPI_LINUX_ETHTOOL_H -#include <linux/kernel.h> +#include <linux/const.h> #include <linux/types.h> #include <linux/if_ether.h>
include/uapi/linux/kernel.h +1 -8
@@ -3,13 +3,6 @@#define _UAPI_LINUX_KERNEL_H#include <linux/sysinfo.h> - -/* -* 'kernel.h' contains some often-used function prototypes etc -*/ -#define __ALIGN_KERNEL (x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) -#define __ALIGN_KERNEL_MASK (x, mask) (((x) + (mask)) & ~(mask)) - -#define __KERNEL_DIV_ROUND_UP (n, d) (((n) + (d) - 1) / (d)) +#include <linux/const.h> #endif /* _UAPI_LINUX_KERNEL_H */
include/uapi/linux/lightnvm.h +1 -1
@@ -21,7 +21,7 @@#define _UAPI_LINUX_LIGHTNVM_H#ifdef __KERNEL__ -#include <linux/kernel.h> +#include <linux/const.h> #include <linux/ioctl.h> #else /* __KERNEL__ */ #include <stdio.h>
include/uapi/linux/mroute6.h +1 -1
@@ -2,7 +2,7 @@#ifndef _UAPI__LINUX_MROUTE6_H#define _UAPI__LINUX_MROUTE6_H -#include <linux/kernel.h> +#include <linux/const.h> #include <linux/types.h> #include <linux/sockios.h> #include <linux/in6.h> /* For struct sockaddr_in6. */
include/uapi/linux/netfilter/x_tables.h +1 -1
@@ -1,7 +1,7 @@/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef _UAPI_X_TABLES_H#define _UAPI_X_TABLES_H -#include <linux/kernel.h> +#include <linux/const.h> #include <linux/types.h> #define XT_FUNCTION_MAXNAMELEN 30
include/uapi/linux/netlink.h +1 -1
@@ -2,7 +2,7 @@#ifndef _UAPI__LINUX_NETLINK_H#define _UAPI__LINUX_NETLINK_H -#include <linux/kernel.h> +#include <linux/const.h> #include <linux/socket.h> /* for __kernel_sa_family_t */ #include <linux/types.h>
include/uapi/linux/sysctl.h +1 -1
@@ -23,7 +23,7 @@#ifndef _UAPI_LINUX_SYSCTL_H#define _UAPI_LINUX_SYSCTL_H -#include <linux/kernel.h> +#include <linux/const.h> #include <linux/types.h> #include <linux/compiler.h>
Greg Kroah-Hartman
maintainerPATCH 23/63 tools headers UAPI: Sync linux/const.h with the kernel headers
In reply to Greg Kroah-HartmanFrom: Arnaldo Carvalho de Melo <[email protected]>
commit 7ddcdea5b54492f54700f427f58690cf1e187e5e upstream.
To pick up the changes in:
a85cbe6159ffc973 ("uapi: move constants from <linux/kernel.h> to <linux/const.h>")
That causes no changes in tooling, just addresses this perf build warning:
Warning: Kernel ABI header at 'tools/include/uapi/linux/const.h' differs from latest version at 'include/uapi/linux/const.h' diff -u tools/include/uapi/linux/const.h include/uapi/linux/const.h
--- tools/include/uapi/linux/const.h | 5 +++++ 1 file changed, 5 insertions(+)
tools/include/uapi/linux/const.h +5 -0
@@ -28,4 +28,9 @@#define _BITUL (x) (_UL(1) << (x))#define _BITULL (x) (_ULL(1) << (x)) +#define __ALIGN_KERNEL (x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) +#define __ALIGN_KERNEL_MASK (x, mask) (((x) + (mask)) & ~(mask)) + +#define __KERNEL_DIV_ROUND_UP (n, d) (((n) + (d) - 1) / (d)) +#endif /* _UAPI_LINUX_CONST_H */
Greg Kroah-Hartman
maintainerPATCH 24/63 cgroup: Fix memory leak when parsing multiple source parameters
In reply to Greg Kroah-HartmanFrom: Qinglang Miao <[email protected]>
commit 2d18e54dd8662442ef5898c6bdadeaf90b3cebbc upstream.
A memory leak is found in cgroup1_parse_param() when multiple source parameters overwrite fc->source in the fs_context struct without free.
unreferenced object 0xffff888100d930e0 (size 16):
comm "mount", pid 520, jiffies 4303326831 (age 152.783s) hex dump (first 16 bytes):
74 65 73 74 6c 65 61 6b 00 00 00 00 00 00 00 00 testleak........
backtrace:
[<000000003e5023ec>] kmemdup_nul+0x2d/0xa0
[<00000000377dbdaa>] vfs_parse_fs_string+0xc0/0x150
[<00000000cb2b4882>] generic_parse_monolithic+0x15a/0x1d0
[<000000000f750198>] path_mount+0xee1/0x1820
[<0000000004756de2>] do_mount+0xea/0x100
[<0000000094cafb0a>] __x64_sys_mount+0x14b/0x1f0Fix this bug by permitting a single source parameter and rejecting with an error all subsequent ones.
--- kernel/cgroup/cgroup-v1.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/cgroup/cgroup-v1.c +2 -0
@@ -908,6 +908,8 @@ int cgroup1_parse_param(struct fs_contex opt =fs_parse (fc, cgroup1_fs_parameters, param, &result);if (opt == -ENOPARAM ) {if (strcmp (param->key,"source" ) ==0 ) { +if (fc->source) +return invalf (fc,"Multiple sources not supported" ); fc->source = param->string; param->string =NULL ;return 0 ;
Greg Kroah-Hartman
maintainerPATCH 25/63 zlib: move EXPORT_SYMBOL() and MODULE_LICENSE() out of dfltcc_syms.c
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
commit 605cc30dea249edf1b659e7d0146a2cf13cbbf71 upstream.
In commit 11fb479ff5d9 ("zlib: export S390 symbols for zlib modules"), I added EXPORT_SYMBOL()s to dfltcc_inflate.c but then Mikhail said that these should probably be in dfltcc_syms.c with the other EXPORT_SYMBOL()s.
However, that is contrary to the current kernel style, which places EXPORT_SYMBOL() immediately after the function that it applies to, so move all EXPORT_SYMBOL()s to their respective function locations and drop the dfltcc_syms.c file. Also move MODULE_LICENSE() from the deleted file to dfltcc.c.
--- lib/zlib_dfltcc/Makefile | 2 +- lib/zlib_dfltcc/dfltcc.c | 6 +++++- lib/zlib_dfltcc/dfltcc_deflate.c | 3 +++ lib/zlib_dfltcc/dfltcc_syms.c | 17 ----------------- 4 files changed, 9 insertions(+), 19 deletions(-)
lib/zlib_dfltcc/Makefile +1 -1
@@ -8,4 +8,4 @@ obj-$(CONFIG_ZLIB_DFLTCC) += zlib_dfltcc.o -zlib_dfltcc-objs := dfltcc.o dfltcc_deflate.o dfltcc_inflate.o dfltcc_syms.o +zlib_dfltcc-objs := dfltcc.o dfltcc_deflate.o dfltcc_inflate.o
lib/zlib_dfltcc/dfltcc.c +5 -1
@@ -1,7 +1,8 @@// SPDX-License-Identifier: Zlib /* dfltcc.c - SystemZ DEFLATE CONVERSION CALL support. */ -#include <linux/zutil.h> +#include <linux/export.h> +#include <linux/module.h> #include "dfltcc_util.h" #include "dfltcc.h"
@@ -53,3 +54,6 @@ void dfltcc_reset( dfltcc_state->dht_threshold =DFLTCC_DHT_MIN_SAMPLE_SIZE ; dfltcc_state->param.ribm =DFLTCC_RIBM ; } +EXPORT_SYMBOL (dfltcc_reset); + +MODULE_LICENSE ("GPL" );
lib/zlib_dfltcc/dfltcc_deflate.c +3 -0
@@ -4,6 +4,7 @@#include "dfltcc_util.h" #include "dfltcc.h" #include <asm/setup.h> +#include <linux/export.h> #include <linux/zutil.h> /*
@@ -34,6 +35,7 @@ int dfltcc_can_deflate(return 1 ; } +EXPORT_SYMBOL (dfltcc_can_deflate);static void dfltcc_gdht ( z_streamp strm
@@ -277,3 +279,4 @@ again: goto again;/* deflate() must use all input or all output */ return 1 ; } +EXPORT_SYMBOL (dfltcc_deflate);
lib/zlib_dfltcc/dfltcc_syms.c deleted +0 -17
@@ -1,17 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* -* linux/lib/zlib_dfltcc/dfltcc_syms.c -* -* Exported symbols for the s390 zlib dfltcc support. -* -*/ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/zlib.h> -#include "dfltcc.h" - -EXPORT_SYMBOL (dfltcc_can_deflate); -EXPORT_SYMBOL (dfltcc_deflate); -EXPORT_SYMBOL (dfltcc_reset); -MODULE_LICENSE ("GPL" );
Greg Kroah-Hartman
maintainerPATCH 26/63 scsi: cxgb4i: Fix TLS dependency
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
commit cb5253198f10a4cd79b7523c581e6173c7d49ddb upstream.
SCSI_CXGB4_ISCSI selects CHELSIO_T4. The latter depends on TLS || TLS=n, so since 'select' does not check dependencies of the selected symbol, SCSI_CXGB4_ISCSI should also depend on TLS || TLS=n.
This prevents the following kconfig warning and restricts SCSI_CXGB4_ISCSI to 'm' whenever TLS=m.
WARNING: unmet direct dependencies detected for CHELSIO_T4
Depends on [m]: NETDEVICES [=y] && ETHERNET [=y] && NET_VENDOR_CHELSIO [=y] && PCI [=y] && (IPV6 [=y] || IPV6 [=y]=n) && (TLS [=m] || TLS [=m]=n) Selected by [y]:
- SCSI_CXGB4_ISCSI [=y] && SCSI_LOWLEVEL [=y] && SCSI [=y] && PCI [=y] && INET [=y] && (IPV6 [=y] || IPV6 [=y]=n) && ETHERNET [=y]
--- drivers/scsi/cxgbi/cxgb4i/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/cxgbi/cxgb4i/Kconfig +1 -0
@@ -4,6 +4,7 @@ config SCSI_CXGB4_ISCSI depends on PCI && INET && (IPV6 || IPV6=n) depends on THERMAL || !THERMAL depends on ETHERNET + depends on TLS || TLS=n select NET_VENDOR_CHELSIO select CHELSIO_T4 select CHELSIO_LIB
Greg Kroah-Hartman
maintainerPATCH 27/63 Bluetooth: hci_h5: close serdev device and free hu in h5_close
In reply to Greg Kroah-HartmanFrom: Anant Thazhemadam <[email protected]>
commit 70f259a3f4276b71db365b1d6ff1eab805ea6ec3 upstream.
When h5_close() gets called, the memory allocated for the hu gets freed only if hu->serdev doesn't exist. This leads to a memory leak. So when h5_close() is requested, close the serdev device instance and free the memory allocated to the hu entirely instead.
--- drivers/bluetooth/hci_h5.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/bluetooth/hci_h5.c +6 -2
@@ -251,8 +251,12 @@ static int h5_close(struct hci_uart *hu)if (h5->vnd && h5->vnd->close) h5->vnd->close (h5); -if (!hu->serdev) -kfree (h5); +if (hu->serdev) +serdev_device_close (hu->serdev); + +kfree_skb (h5->rx_skb); +kfree (h5); + h5 =NULL ;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 28/63 fbcon: Disable accelerated scrolling
In reply to Greg Kroah-HartmanFrom: Daniel Vetter <daniel.vetter-/[email protected]>
commit 39aead8373b3c20bb5965c024dfb51a94e526151 upstream.
So ever since syzbot discovered fbcon, we have solid proof that it's full of bugs. And often the solution is to just delete code and remove features, e.g. 50145474f6ef ("fbcon: remove soft scrollback code").
Now the problem is that most modern-ish drivers really only treat fbcon as an dumb kernel console until userspace takes over, and Oops printer for some emergencies. Looking at drm drivers and the basic vesa/efi fbdev drivers shows that only 3 drivers support any kind of acceleration:
- nouveau, seems to be enabled by default
- omapdrm, when a DMM remapper exists using remapper rewriting for y/xpanning
- gma500, but that is getting deleted now for the GTT remapper trick, and the accelerated copyarea never set the FBINFO_HWACCEL_COPYAREA flag, so unused (and could be deleted already I think).
No other driver supportes accelerated fbcon. And fbcon is the only user of this accel code (it's not exposed as uapi through ioctls), which means we could garbage collect fairly enormous amounts of code if we kill this.
Plus because syzbot only runs on virtual hardware, and none of the drivers for that have acceleration, we'd remove a huge gap in testing. And there's no other even remotely comprehensive testing aside from syzbot.
This patch here just disables the acceleration code by always redrawing when scrolling. The plan is that once this has been merged for well over a year in released kernels, we can start to go around and delete a lot of code.
v2:
- Drop a few more unused local variables, somehow I missed the compiler warnings (Sam)
- Fix typo in comment (Jiri)
- add a todo entry for the cleanup (Thomas)
v3: Remove more unused variables (0day)
--- Documentation/gpu/todo.rst | 18 +++++++++++++++ drivers/video/fbdev/core/fbcon.c | 45 ++++++--------------------------------- 2 files changed, 26 insertions(+), 37 deletions(-)
Documentation/gpu/todo.rst +18 -0
@@ -273,6 +273,24 @@ Contact: Daniel Vetter, Noralf Tronnes Level: Advanced +Garbage collect fbdev scrolling acceleration +-------------------------------------------- + +Scroll acceleration is disabled in fbcon by hard-wiring p->scrollmode = +SCROLL_REDRAW. There's a ton of code this will allow us to remove: +- lots of code in fbcon.c +- a bunch of the hooks in fbcon_ops, maybe the remaining hooks could be called + directly instead of the function table (with a switch on p->rotate) +- fb_copyarea is unused after this, and can be deleted from all drivers + +Note that not all acceleration code can be deleted, since clearing and cursor +support is still accelerated, which might be good candidates for further +deletion projects. + +Contact: Daniel Vetter + +Level: Intermediate + idr_init_base() ---------------
drivers/video/fbdev/core/fbcon.c +8 -37
78 lines not on this page · raw message
Re: [PATCH 5.10 28/63] fbcon: Disable accelerated scrolling
Quoted 14 lines · Greg Kroah-Hartman
From: Daniel Vetter <daniel.vetter-/[email protected]>
commit
39aead8373b3c20bb5965c024dfb51a94e526151upstream.So ever since syzbot discovered fbcon, we have solid proof that it's full of bugs. And often the solution is to just delete code and remove features, e.g.
50145474f6ef("fbcon: remove soft scrollback code").Now the problem is that most modern-ish drivers really only treat fbcon as an dumb kernel console until userspace takes over, and Oops printer for some emergencies. Looking at drm drivers and the basic vesa/efi fbdev drivers shows that only 3 drivers support any kind of acceleration:
Quoted 8 lines
- nouveau, seems to be enabled by default
- omapdrm, when a DMM remapper exists using remapper rewriting for y/xpanning
- gma500, but that is getting deleted now for the GTT remapper trick, and the accelerated copyarea never set theFBINFO_HWACCEL_COPYAREAflag, so unused (and could be deleted already I think).No other driver supportes accelerated fbcon. And fbcon is the only
Note that there are 32 more drivers using acceleration under drivers/video/fbdev/.
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Greg Kroah-Hartman
maintainerPATCH 29/63 reiserfs: add check for an invalid ih_entry_count
In reply to Greg Kroah-HartmanFrom: Rustam Kovhaev <[email protected]>
commit d24396c5290ba8ab04ba505176874c4e04a2d53c upstream.
when directory item has an invalid value set for ih_entry_count it might trigger use-after-free or out-of-bounds read in bin_search_in_dir_item()
ih_entry_count * IH_SIZE for directory item should not be larger than ih_item_len
--- fs/reiserfs/stree.c | 6 ++++++ 1 file changed, 6 insertions(+)
fs/reiserfs/stree.c +6 -0
@@ -454,6 +454,12 @@ static int is_leaf(char *buf, int blocks "(second one): %h", ih);return 0 ; } +if (is_direntry_le_ih (ih) && (ih_item_len (ih) < (ih_entry_count (ih) *IH_SIZE ))) { +reiserfs_warning (NULL ,"reiserfs-5093" , +"item entry count seems wrong %h" , + ih); +return 0 ; + } prev_location =ih_location (ih); }
Greg Kroah-Hartman
maintainerPATCH 30/63 misc: vmw_vmci: fix kernel info-leak by initializing dbells in vmci_ctx_get_chkpt_doorbells()
In reply to Greg Kroah-HartmanFrom: Anant Thazhemadam <[email protected]>
commit 31dcb6c30a26d32650ce134820f27de3c675a45a upstream.
A kernel-infoleak was reported by syzbot, which was caused because dbells was left uninitialized.
Using kzalloc() instead of kmalloc() fixes this issue.
--- drivers/misc/vmw_vmci/vmci_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/misc/vmw_vmci/vmci_context.c +1 -1
@@ -743,7 +743,7 @@ static int vmci_ctx_get_chkpt_doorbells(return VMCI_ERROR_MORE_DATA ; } - dbells =kmalloc (data_size,GFP_ATOMIC ); + dbells =kzalloc (data_size,GFP_ATOMIC );if (!dbells)return VMCI_ERROR_NO_MEM ;
Greg Kroah-Hartman
maintainerPATCH 31/63 media: gp8psk: initialize stats at power control logic
In reply to Greg Kroah-HartmanFrom: Mauro Carvalho Chehab <[email protected]>
commit d0ac1a26ed5943127cb0156148735f5f52a07075 upstream.
As reported on:
https://lore.kernel.org/linux-media/[email protected]/
if gp8psk_usb_in_op() returns an error, the status var is not initialized. Yet, this var is used later on, in order to identify:
- if the device was already started;
- if firmware has loaded;
- if the LNBf was powered on.
Using status = 0 seems to ensure that everything will be properly powered up.
So, instead of the proposed solution, let's just set status = 0.
--- drivers/media/usb/dvb-usb/gp8psk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/usb/dvb-usb/gp8psk.c +1 -1
@@ -182,7 +182,7 @@ out_rel_fw:static int gp8psk_power_ctrl (struct dvb_usb_device *d,int onoff) { -u8 status, buf; +u8 status =0 , buf;int gp_product_id =le16_to_cpu (d->udev->descriptor.idProduct);if (onoff) {
Greg Kroah-Hartman
maintainerPATCH 32/63 f2fs: fix shift-out-of-bounds in sanity_check_raw_super()
In reply to Greg Kroah-HartmanFrom: Chao Yu <[email protected]>
commit e584bbe821229a3e7cc409eecd51df66f9268c21 upstream.
syzbot reported a bug which could cause shift-out-of-bounds issue, fix it.
Call Trace: __dump_stack lib/dump_stack.c:79 [inline] dump_stack+0x107/0x163 lib/dump_stack.c:120 ubsan_epilogue+0xb/0x5a lib/ubsan.c:148 __ubsan_handle_shift_out_of_bounds.cold+0xb1/0x181 lib/ubsan.c:395 sanity_check_raw_super fs/f2fs/super.c:2812 [inline] read_raw_super_block fs/f2fs/super.c:3267 [inline] f2fs_fill_super.cold+0x16c9/0x16f6 fs/f2fs/super.c:3519 mount_bdev+0x34d/0x410 fs/super.c:1366 legacy_get_tree+0x105/0x220 fs/fs_context.c:592 vfs_get_tree+0x89/0x2f0 fs/super.c:1496 do_new_mount fs/namespace.c:2896 [inline] path_mount+0x12ae/0x1e70 fs/namespace.c:3227 do_mount fs/namespace.c:3240 [inline] __do_sys_mount fs/namespace.c:3448 [inline] __se_sys_mount fs/namespace.c:3425 [inline] __x64_sys_mount+0x27f/0x300 fs/namespace.c:3425 do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46 entry_SYSCALL_64_after_hwframe+0x44/0xa9
--- fs/f2fs/super.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
fs/f2fs/super.c +4 -5
@@ -2744,7 +2744,6 @@ static int sanity_check_raw_super(structblock_t total_sections, blocks_per_seg;struct f2fs_super_block *raw_super = (struct f2fs_super_block *) (bh->b_data +F2FS_SUPER_OFFSET ); -unsigned int blocksize;size_t crc_offset =0 ;__u32 crc =0 ;
@@ -2778,10 +2777,10 @@ static int sanity_check_raw_super(struct }/* Currently, support only 4KB block size */ - blocksize =1 <<le32_to_cpu (raw_super->log_blocksize); -if (blocksize !=F2FS_BLKSIZE ) { -f2fs_info (sbi,"Invalid blocksize (%u), supports only 4KB" , - blocksize); +if (le32_to_cpu (raw_super->log_blocksize) !=F2FS_BLKSIZE_BITS ) { +f2fs_info (sbi,"Invalid log_blocksize (%u), supports only %u" , +le32_to_cpu (raw_super->log_blocksize), +F2FS_BLKSIZE_BITS );return -EFSCORRUPTED ; }
Greg Kroah-Hartman
maintainerPATCH 33/63 ALSA: seq: Use bool for snd_seq_queue internal flags
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 4ebd47037027c4beae99680bff3b20fdee5d7c1e upstream.
The snd_seq_queue struct contains various flags in the bit fields. Those are categorized to two different use cases, both of which are protected by different spinlocks. That implies that there are still potential risks of the bad operations for bit fields by concurrent accesses.
For addressing the problem, this patch rearranges those flags to be a standard bool instead of a bit field.
--- sound/core/seq/seq_queue.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
sound/core/seq/seq_queue.h +4 -4
@@ -26,10 +26,10 @@ struct snd_seq_queue {struct snd_seq_timer *timer;/* time keeper for this queue */ int owner;/* client that 'owns' the timer */ - unsigned int locked:1, /* timer is only accesibble by owner if set */ - klocked:1, /* kernel lock (after START) */ - check_again:1, - check_blocked:1; +bool locked;/* timer is only accesibble by owner if set */ +bool klocked;/* kernel lock (after START) */ +bool check_again;/* concurrent access happened during check */ +bool check_blocked;/* queue being checked */ unsigned int flags;/* status flags */ unsigned int info_flags;/* info for sync */
Greg Kroah-Hartman
maintainerPATCH 34/63 ALSA: rawmidi: Access runtime->avail always in spinlock
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
commit 88a06d6fd6b369d88cec46c62db3e2604a2f50d5 upstream.
The runtime->avail field may be accessed concurrently while some places refer to it without taking the runtime->lock spinlock, as detected by KCSAN. Usually this isn't a big problem, but for consistency and safety, we should take the spinlock at each place referencing this field.
--- sound/core/rawmidi.c | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-)
sound/core/rawmidi.c +35 -14
@@ -95,11 +95,21 @@ static inline unsigned short snd_rawmidi } } -static inline int snd_rawmidi_ready (struct snd_rawmidi_substream *substream) +static inline bool __snd_rawmidi_ready (struct snd_rawmidi_runtime *runtime) +{ +return runtime->avail >= runtime->avail_min; +} + +static bool snd_rawmidi_ready (struct snd_rawmidi_substream *substream) {struct snd_rawmidi_runtime *runtime = substream->runtime; +unsigned long flags; +bool ready; -return runtime->avail >= runtime->avail_min; +spin_lock_irqsave (&runtime->lock, flags); + ready =__snd_rawmidi_ready (runtime); +spin_unlock_irqrestore (&runtime->lock, flags); +return ready; } static inline int snd_rawmidi_ready_append(struct snd_rawmidi_substream *substream,
@@ -1019,7 +1029,7 @@ int snd_rawmidi_receive(struct snd_rawmiif (result >0 ) {if (runtime->event)schedule_work (&runtime->event_work); -else if (snd_rawmidi_ready (substream)) +else if (__snd_rawmidi_ready (runtime))wake_up (&runtime->sleep); }spin_unlock_irqrestore (&runtime->lock, flags);
@@ -1098,7 +1108,7 @@ static ssize_t snd_rawmidi_read(struct f result =0 ;while (count >0 ) {spin_lock_irq (&runtime->lock); -while (!snd_rawmidi_ready (substream)) { +while (!__snd_rawmidi_ready (runtime)) {wait_queue_entry_t wait;if ((file->f_flags &O_NONBLOCK ) !=0 || result >0 ) {
@@ -1115,9 +1125,11 @@ static ssize_t snd_rawmidi_read(struct freturn -ENODEV ;if (signal_pending (current))return result >0 ? result : -ERESTARTSYS ; -if (!runtime->avail) -return result >0 ? result : -EIO ;spin_lock_irq (&runtime->lock); +if (!runtime->avail) { +spin_unlock_irq (&runtime->lock); +return result >0 ? result : -EIO ; + } }spin_unlock_irq (&runtime->lock); count1 = snd_rawmidi_kernel_read1(substream,
@@ -1255,7 +1267,7 @@ int __snd_rawmidi_transmit_ack(struct sn runtime->avail += count; substream->bytes += count;if (count >0 ) { -if (runtime->drain ||snd_rawmidi_ready (substream)) +if (runtime->drain ||__snd_rawmidi_ready (runtime))wake_up (&runtime->sleep); }return count;
@@ -1444,9 +1456,11 @@ static ssize_t snd_rawmidi_write(structreturn -ENODEV ;if (signal_pending (current))return result >0 ? result : -ERESTARTSYS ; -if (!runtime->avail && !timeout) -return result >0 ? result : -EIO ;spin_lock_irq (&runtime->lock); +if (!runtime->avail && !timeout) { +spin_unlock_irq (&runtime->lock); +return result >0 ? result : -EIO ; + } }spin_unlock_irq (&runtime->lock); count1 =snd_rawmidi_kernel_write1 (substream, buf,NULL , count);
@@ -1526,6 +1540,7 @@ static void snd_rawmidi_proc_info_read(sstruct snd_rawmidi *rmidi;struct snd_rawmidi_substream *substream;struct snd_rawmidi_runtime *runtime; +unsigned long buffer_size, avail, xruns; rmidi = entry->private_data;snd_iprintf (buffer,"%s\n\n" , rmidi->name);
@@ -1544,13 +1559,16 @@ static void snd_rawmidi_proc_info_read(s" Owner PID : %d\n" , pid_vnr(substream->pid)); runtime = substream->runtime; +spin_lock_irq (&runtime->lock); + buffer_size = runtime->buffer_size; + avail = runtime->avail; +spin_unlock_irq (&runtime->lock);snd_iprintf (buffer," Mode : %s\n" " Buffer size : %lu\n" " Avail : %lu\n" , runtime->oss ?"OSS compatible" :"native" , - (unsigned long ) runtime->buffer_size, - (unsigned long ) runtime->avail); + buffer_size, avail); } } }
@@ -1568,13 +1586,16 @@ static void snd_rawmidi_proc_info_read(s" Owner PID : %d\n" , pid_vnr(substream->pid)); runtime = substream->runtime; +spin_lock_irq (&runtime->lock); + buffer_size = runtime->buffer_size; + avail = runtime->avail; + xruns = runtime->xruns; +spin_unlock_irq (&runtime->lock);snd_iprintf (buffer," Buffer size : %lu\n" " Avail : %lu\n" " Overruns : %lu\n" , - (unsigned long ) runtime->buffer_size, - (unsigned long ) runtime->avail, - (unsigned long ) runtime->xruns); + buffer_size, avail, xruns); } } }
Greg Kroah-Hartman
maintainerPATCH 35/63 bfs: dont use WARNING: string when its just info.
In reply to Greg Kroah-HartmanFrom: Randy Dunlap <[email protected]>
commit dc889b8d4a8122549feabe99eead04e6b23b6513 upstream.
Make the printk() [bfs "printf" macro] seem less severe by changing "WARNING:" to "NOTE:".
<asm-generic/bug.h> warns us about using WARNING or BUG in a format string other than in WARN() or BUG() family macros. bfs/inode.c is doing just that in a normal printk() call, so change the "WARNING" string to be "NOTE".
--- fs/bfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/bfs/inode.c +1 -1
@@ -350,7 +350,7 @@ static int bfs_fill_super(struct super_b info->si_lasti = (le32_to_cpu (bfs_sb->s_start) -BFS_BSIZE ) /sizeof (struct bfs_inode ) +BFS_ROOT_INO -1 ;if (info->si_lasti ==BFS_MAX_LASTI ) -printf ("WARNING: filesystem %s was created with 512 inodes, the real maximum is 511, mounting anyway\n" , s->s_id); +printf ("NOTE: filesystem %s was created with 512 inodes, the real maximum is 511, mounting anyway\n" , s->s_id);else if (info->si_lasti >BFS_MAX_LASTI ) {printf ("Impossible last inode number %lu > %d on %s\n" , info->si_lasti,BFS_MAX_LASTI , s->s_id); goto out1;
Greg Kroah-Hartman
maintainerPATCH 36/63 ext4: check for invalid block size early when mounting a file system
In reply to Greg Kroah-HartmanFrom: Theodore Ts'o <[email protected]>
commit c9200760da8a728eb9767ca41a956764b28c1310 upstream.
Check for valid block size directly by validating s_log_block_size; we were doing this in two places. First, by calculating blocksize via BLOCK_SIZE << s_log_block_size, and then checking that the blocksize was valid. And then secondly, by checking s_log_block_size directly.
The first check is not reliable, and can trigger an UBSAN warning if s_log_block_size on a maliciously corrupted superblock is greater than
22. This is harmless, since the second test will correctly reject the maliciously fuzzed file system, but to make syzbot shut up, and because the two checks are duplicative in any case, delete the blocksize check, and move the s_log_block_size earlier in ext4_fill_super().
--- fs/ext4/super.c | 40 ++++++++++++++++------------------------ 1 file changed, 16 insertions(+), 24 deletions(-)
fs/ext4/super.c +16 -24
@@ -4186,18 +4186,25 @@ static int ext4_fill_super(struct super_*/ sbi->s_li_wait_mult =EXT4_DEF_LI_WAIT_MULT ; - blocksize =BLOCK_SIZE <<le32_to_cpu (es->s_log_block_size); - -if (blocksize ==PAGE_SIZE ) -set_opt (sb,DIOREAD_NOLOCK ); - -if (blocksize <EXT4_MIN_BLOCK_SIZE || - blocksize >EXT4_MAX_BLOCK_SIZE ) { +if (le32_to_cpu (es->s_log_block_size) > + (EXT4_MAX_BLOCK_LOG_SIZE -EXT4_MIN_BLOCK_LOG_SIZE )) {ext4_msg (sb,KERN_ERR , -"Unsupported filesystem blocksize %d (%d log_block_size)" , - blocksize,le32_to_cpu (es->s_log_block_size)); +"Invalid log block size: %u" , +le32_to_cpu (es->s_log_block_size)); goto failed_mount; } +if (le32_to_cpu (es->s_log_cluster_size) > + (EXT4_MAX_CLUSTER_LOG_SIZE -EXT4_MIN_BLOCK_LOG_SIZE )) { +ext4_msg (sb,KERN_ERR , +"Invalid log cluster size: %u" , +le32_to_cpu (es->s_log_cluster_size)); + goto failed_mount; + } + + blocksize =EXT4_MIN_BLOCK_SIZE <<le32_to_cpu (es->s_log_block_size); + +if (blocksize ==PAGE_SIZE ) +set_opt (sb,DIOREAD_NOLOCK );if (le32_to_cpu (es->s_rev_level) ==EXT4_GOOD_OLD_REV ) { sbi->s_inode_size =EXT4_GOOD_OLD_INODE_SIZE ;
@@ -4416,21 +4423,6 @@ static int ext4_fill_super(struct super_if (!ext4_feature_set_ok (sb, (sb_rdonly (sb)))) goto failed_mount; -if (le32_to_cpu (es->s_log_block_size) > - (EXT4_MAX_BLOCK_LOG_SIZE -EXT4_MIN_BLOCK_LOG_SIZE )) { -ext4_msg (sb,KERN_ERR , -"Invalid log block size: %u" , -le32_to_cpu (es->s_log_block_size)); - goto failed_mount; - } -if (le32_to_cpu (es->s_log_cluster_size) > - (EXT4_MAX_CLUSTER_LOG_SIZE -EXT4_MIN_BLOCK_LOG_SIZE )) { -ext4_msg (sb,KERN_ERR , -"Invalid log cluster size: %u" , -le32_to_cpu (es->s_log_cluster_size)); - goto failed_mount; - } -if (le16_to_cpu (sbi->s_es->s_reserved_gdt_blocks) > (blocksize /4 )) { ext4_msg(sb, KERN_ERR, "Number of reserved GDT blocks insanely large: %d",
Greg Kroah-Hartman
maintainerPATCH 37/63 fcntl: Fix potential deadlock in send_sig{io, urg}()
In reply to Greg Kroah-HartmanFrom: Boqun Feng <[email protected]>
commit 8d1ddb5e79374fb277985a6b3faa2ed8631c5b4c upstream.
Syzbot reports a potential deadlock found by the newly added recursive read deadlock detection in lockdep:
[...] ========================================================
[...] WARNING: possible irq lock inversion dependency detected
[...] 5.9.0-rc2-syzkaller #0 Not tainted
[...] --------------------------------------------------------
[...] syz-executor.1/10214 just changed the state of lock:
[...] ffff88811f506338 (&f->f_owner.lock){.+..}-{2:2}, at: send_sigurg+0x1d/0x200 [...] but this lock was taken by another, HARDIRQ-safe lock in the past:
[...] (&dev->event_lock){-...}-{2:2}
[...]
[...]
[...] and interrupts could create inverse lock ordering between them. [...]
[...]
[...] other info that might help us debug this:
[...] Chain exists of:
[...] &dev->event_lock --> &new->fa_lock --> &f->f_owner.lock
[...]
[...] Possible interrupt unsafe locking scenario:
[...]
[...] CPU0 CPU1 [...] ---- ---- [...] lock(&f->f_owner.lock); [...] local_irq_disable(); [...] lock(&dev->event_lock); [...] lock(&new->fa_lock);
[...] <Interrupt>
[...] lock(&dev->event_lock);
[...]
[...] *** DEADLOCK ***
The corresponding deadlock case is as followed:
CPU 0 CPU 1 CPU 2 read_lock(&fown->lock); spin_lock_irqsave(&dev->event_lock, ...) write_lock_irq(&filp->f_owner.lock); // wait for the lock read_lock(&fown-lock); // have to wait until the writer release // due to the fairness <interrupted> spin_lock_irqsave(&dev->event_lock); // wait for the lock
The lock dependency on CPU 1 happens if there exists a call sequence:
input_inject_event(): spin_lock_irqsave(&dev->event_lock,...); input_handle_event(): input_pass_values(): input_to_handler(): handler->event(): // evdev_event() evdev_pass_values(): spin_lock(&client->buffer_lock); __pass_event(): kill_fasync(): kill_fasync_rcu(): read_lock(&fa->fa_lock); send_sigio(): read_lock(&fown->lock);
To fix this, make the reader in send_sigurg() and send_sigio() use read_lock_irqsave() and read_lock_irqrestore().
--- fs/fcntl.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
fs/fcntl.c +6 -4
@@ -781,9 +781,10 @@ void send_sigio(struct fown_struct *fown {struct task_struct *p;enum pid_type type; +unsigned long flags;struct pid *pid; -read_lock (&fown->lock); +read_lock_irqsave (&fown->lock, flags); type = fown->pid_type; pid = fown->pid;
@@ -804,7 +805,7 @@ void send_sigio(struct fown_struct *fownread_unlock (&tasklist_lock); } out_unlock_fown: -read_unlock (&fown->lock); +read_unlock_irqrestore (&fown->lock, flags); } static void send_sigurg_to_task(struct task_struct *p,
@@ -819,9 +820,10 @@ int send_sigurg(struct fown_struct *fownstruct task_struct *p;enum pid_type type;struct pid *pid; +unsigned long flags;int ret =0 ; -read_lock (&fown->lock); +read_lock_irqsave (&fown->lock, flags); type = fown->pid_type; pid = fown->pid;
@@ -844,7 +846,7 @@ int send_sigurg(struct fown_struct *fownread_unlock (&tasklist_lock); } out_unlock_fown: -read_unlock (&fown->lock); +read_unlock_irqrestore (&fown->lock, flags);return ret; }
Greg Kroah-Hartman
maintainerPATCH 38/63 io_uring: check kthread stopped flag when sq thread is unparked
In reply to Greg Kroah-HartmanFrom: Xiaoguang Wang <[email protected]>
commit 65b2b213484acd89a3c20dbb524e52a2f3793b78 upstream.
syzbot reports following issue:
INFO: task syz-executor.2:12399 can't die for more than 143 seconds.
task:syz-executor.2 state:D stack:28744 pid:12399 ppid: 8504 flags:0x00004004
Call Trace:
context_switch kernel/sched/core.c:3773 [inline]
__schedule+0x893/0x2170 kernel/sched/core.c:4522
schedule+0xcf/0x270 kernel/sched/core.c:4600
schedule_timeout+0x1d8/0x250 kernel/time/timer.c:1847
do_wait_for_common kernel/sched/completion.c:85 [inline]
__wait_for_common kernel/sched/completion.c:106 [inline]
wait_for_common kernel/sched/completion.c:117 [inline]
wait_for_completion+0x163/0x260 kernel/sched/completion.c:138
kthread_stop+0x17a/0x720 kernel/kthread.c:596
io_put_sq_data fs/io_uring.c:7193 [inline]
io_sq_thread_stop+0x452/0x570 fs/io_uring.c:7290
io_finish_async fs/io_uring.c:7297 [inline]
io_sq_offload_create fs/io_uring.c:8015 [inline]
io_uring_create fs/io_uring.c:9433 [inline]
io_uring_setup+0x19b7/0x3730 fs/io_uring.c:9507
do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x45deb9
Code: Unable to access opcode bytes at RIP 0x45de8f.
RSP: 002b:00007f174e51ac78 EFLAGS: 00000246 ORIG_RAX: 00000000000001a9
RAX: ffffffffffffffda RBX: 0000000000008640 RCX: 000000000045deb9
RDX: 0000000000000000 RSI: 0000000020000140 RDI: 00000000000050e5
RBP: 000000000118bf58 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 000000000118bf2c
R13: 00007ffed9ca723f R14: 00007f174e51b9c0 R15: 000000000118bf2c
INFO: task syz-executor.2:12399 blocked for more than 143 seconds.
Not tainted 5.10.0-rc3-next-20201110-syzkaller #0"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
Currently we don't have a reproducer yet, but seems that there is a race in current codes:
=> io_put_sq_data
ctx_list is empty now. |
==> kthread_park(sqd->thread); |
| T1: sq thread is parked now.
==> kthread_stop(sqd->thread); |
KTHREAD_SHOULD_STOP is set now.|
===> kthread_unpark(k); |
| T2: sq thread is now unparkd, run again.
|
| T3: sq thread is now preempted out.
|
===> wake_up_process(k); |
|
| T4: Since sqd ctx_list is empty, needs_sched will be true,
| then sq thread sets task state to TASK_INTERRUPTIBLE,
| and schedule, now sq thread will never be waken up.
===> wait_for_completion |I have artificially used mdelay() to simulate above race, will get same stack like this syzbot report, but to be honest, I'm not sure this code race triggers syzbot report.
To fix this possible code race, when sq thread is unparked, need to check whether sq thread has been stopped.
--- fs/io_uring.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
fs/io_uring.c +9 -1
@@ -6802,8 +6802,16 @@ static int io_sq_thread(void *data)* kthread parking. This synchronizes the thread vs users, * the users are synchronized on the sqd->ctx_lock. */ -if (kthread_should_park ()) +if (kthread_should_park ()) {kthread_parkme (); +/* +* When sq thread is unparked, in case the previous park operation +* comes from io_put_sq_data(), which means that sq thread is going +* to be stopped, so here needs to have a check. +*/ +if (kthread_should_stop ()) +break ; + }if (unlikely (!list_empty (&sqd->ctx_new_list)))io_sqd_init_new (sqd);
Greg Kroah-Hartman
maintainerPATCH 39/63 rtc: sun6i: Fix memleak in sun6i_rtc_clk_init
In reply to Greg Kroah-HartmanFrom: Dinghao Liu <[email protected]>
[ Upstream commit 28d211919e422f58c1e6c900e5810eee4f1ce4c8 ]
When clk_hw_register_fixed_rate_with_accuracy() fails, clk_data should be freed. It's the same for the subsequent two error paths, but we should also unregister the already registered clocks in them.
--- drivers/rtc/rtc-sun6i.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/rtc/rtc-sun6i.c +5 -3
@@ -272,7 +272,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, 300000000);if (IS_ERR (rtc->int_osc)) {pr_crit ("Couldn't register the internal oscillator\n" ); -return ; + goto err; } parents[0 ] =clk_hw_get_name (rtc->int_osc);
@@ -290,7 +290,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, rtc->losc =clk_register (NULL , &rtc->hw);if (IS_ERR (rtc->losc)) {pr_crit ("Couldn't register the LOSC clock\n" ); -return ; + goto err_register; } of_property_read_string_index(node, "clock-output-names", 1,
@@ -301,7 +301,7 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, &rtc->lock);if (IS_ERR (rtc->ext_losc)) {pr_crit ("Couldn't register the LOSC external gate\n" ); -return ; + goto err_register; } clk_data->num =2 ;
@@ -314,6 +314,8 @@ static void __init sun6i_rtc_clk_init(struct device_node *node,of_clk_add_hw_provider (node, of_clk_hw_onecell_get, clk_data);return ; +err_register: +clk_hw_unregister_fixed_rate (rtc->int_osc); err:kfree (clk_data); }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 40/63 module: set MODULE_STATE_GOING state when a module fails to load
In reply to Greg Kroah-HartmanFrom: Miroslav Benes <[email protected]>
[ Upstream commit 5e8ed280dab9eeabc1ba0b2db5dbe9fe6debb6b5 ]
If a module fails to load due to an error in prepare_coming_module(), the following error handling in load_module() runs with MODULE_STATE_COMING in module's state. Fix it by correctly setting MODULE_STATE_GOING under "bug_cleanup" label.
--- kernel/module.c | 1 + 1 file changed, 1 insertion(+)
kernel/module.c +1 -0
@@ -3991,6 +3991,7 @@ static int load_module(struct load_info *info, const char __user *uargs, MODULE_STATE_GOING, mod);klp_module_going (mod); bug_cleanup: + mod->state =MODULE_STATE_GOING ;/* module_bug_cleanup needs module_mutex protection */ mutex_lock (&module_mutex);module_bug_cleanup (mod);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 41/63 quota: Dont overflow quota file offsets
In reply to Greg Kroah-HartmanFrom: Jan Kara <[email protected]>
[ Upstream commit 10f04d40a9fa29785206c619f80d8beedb778837 ]
The on-disk quota format supports quota files with upto 2^32 blocks. Be careful when computing quota file offsets in the quota files from block numbers as they can overflow 32-bit types. Since quota files larger than 4GB would require ~26 millions of quota users, this is mostly a theoretical concern now but better be careful, fuzzers would find the problem sooner or later anyway...
--- fs/quota/quota_tree.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
fs/quota/quota_tree.c +4 -4
@@ -62,7 +62,7 @@ static ssize_t read_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf)memset (buf,0 , info->dqi_usable_bs);return sb->s_op->quota_read (sb, info->dqi_type, buf, - info->dqi_usable_bs, blk << info->dqi_blocksize_bits); + info->dqi_usable_bs, (loff_t )blk << info->dqi_blocksize_bits); }static ssize_t write_blk (struct qtree_mem_dqinfo *info,uint blk,char *buf)
@@ -71,7 +71,7 @@ static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf)ssize_t ret; ret = sb->s_op->quota_write (sb, info->dqi_type, buf, - info->dqi_usable_bs, blk << info->dqi_blocksize_bits); + info->dqi_usable_bs, (loff_t )blk << info->dqi_blocksize_bits);if (ret != info->dqi_usable_bs) {quota_error (sb,"dquota write failed" );if (ret >=0 )
@@ -284,7 +284,7 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, blk); goto out_buf; } - dquot->dq_off = (blk << info->dqi_blocksize_bits) + + dquot->dq_off = ((loff_t )blk << info->dqi_blocksize_bits) +sizeof (struct qt_disk_dqdbheader ) + i * info->dqi_entry_size;kfree (buf);
@@ -559,7 +559,7 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info, ret = -EIO ; goto out_buf; }else { - ret = (blk << info->dqi_blocksize_bits) +sizeof (struct + ret = ((loff_t )blk << info->dqi_blocksize_bits) +sizeof (struct qt_disk_dqdbheader ) + i * info->dqi_entry_size; } out_buf:
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 42/63 rtc: pl031: fix resource leak in pl031_probe
In reply to Greg Kroah-HartmanFrom: Zheng Liang <[email protected]>
[ Upstream commit 1eab0fea2514b269e384c117f5b5772b882761f0 ]
When devm_rtc_allocate_device is failed in pl031_probe, it should release mem regions with device.
--- drivers/rtc/rtc-pl031.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/rtc/rtc-pl031.c +4 -2
@@ -361,8 +361,10 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)device_init_wakeup (&adev->dev, true); ldata->rtc =devm_rtc_allocate_device (&adev->dev); -if (IS_ERR (ldata->rtc)) -return PTR_ERR (ldata->rtc); +if (IS_ERR (ldata->rtc)) { + ret =PTR_ERR (ldata->rtc); + goto out; + } ldata->rtc->ops = ops; ldata->rtc->range_min = vendor->range_min;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 43/63 powerpc: sysdev: add missing iounmap() on error in mpic_msgr_probe()
In reply to Greg Kroah-HartmanFrom: Qinglang Miao <[email protected]>
[ Upstream commit ffa1797040c5da391859a9556be7b735acbe1242 ]
I noticed that iounmap() of msgr_block_addr before return from mpic_msgr_probe() in the error handling case is missing. So use devm_ioremap() instead of just ioremap() when remapping the message register block, so the mapping will be automatically released on probe failure.
--- arch/powerpc/sysdev/mpic_msgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/sysdev/mpic_msgr.c +1 -1
@@ -191,7 +191,7 @@ static int mpic_msgr_probe(struct platform_device *dev)/* IO map the message register block. */ of_address_to_resource (np,0 , &rsrc); - msgr_block_addr =ioremap (rsrc.start,resource_size (&rsrc)); + msgr_block_addr =devm_ioremap (&dev->dev, rsrc.start,resource_size (&rsrc));if (!msgr_block_addr) {dev_err (&dev->dev,"Failed to iomap MPIC message registers" );return -EFAULT ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 44/63 i3c master: fix missing destroy_workqueue() on error in i3c_master_register
In reply to Greg Kroah-HartmanFrom: Qinglang Miao <[email protected]>
[ Upstream commit 59165d16c699182b86b5c65181013f1fd88feb62 ]
Add the missing destroy_workqueue() before return from i3c_master_register in the error handling case.
--- drivers/i3c/master.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/i3c/master.c +4 -1
@@ -2537,7 +2537,7 @@ int i3c_master_register(struct i3c_master_controller *master, ret =i3c_master_bus_init (master);if (ret) - goto err_put_dev; + goto err_destroy_wq; ret =device_add (&master->dev);if (ret)
@@ -2568,6 +2568,9 @@ int i3c_master_register(struct i3c_master_controller *master, err_cleanup_bus:i3c_master_bus_cleanup (master); +err_destroy_wq: +destroy_workqueue (master->wq); + err_put_dev:put_device (&master->dev);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 45/63 NFSv4: Fix a pNFS layout related use-after-free race when freeing the inode
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
[ Upstream commit b6d49ecd1081740b6e632366428b960461f8158b ]
When returning the layout in nfs4_evict_inode(), we need to ensure that the layout is actually done being freed before we can proceed to free the inode itself.
--- fs/nfs/nfs4super.c | 2 +- fs/nfs/pnfs.c | 33 +++++++++++++++++++++++++++++++-- fs/nfs/pnfs.h | 5 +++++ 3 files changed, 37 insertions(+), 3 deletions(-)
fs/nfs/nfs4super.c +1 -1
@@ -67,7 +67,7 @@ static void nfs4_evict_inode(struct inode *inode)nfs_inode_evict_delegation (inode);/* Note that above delegreturn would trigger pnfs return-on-close */ pnfs_return_layout (inode); -pnfs_destroy_layout (NFS_I (inode)); +pnfs_destroy_layout_final (NFS_I (inode));/* First call standard NFS clear_inode() code */ nfs_clear_inode (inode);nfs4_xattr_cache_zap (inode);
fs/nfs/pnfs.c +31 -2
@@ -294,6 +294,7 @@ void pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo) {struct inode *inode; +unsigned long i_state;if (!lo)return ;
@@ -304,8 +305,12 @@ pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo)if (!list_empty (&lo->plh_segs))WARN_ONCE (1 ,"NFS: BUG unfreed layout segments.\n" );pnfs_detach_layout_hdr (lo); + i_state = inode->i_state;spin_unlock (&inode->i_lock);pnfs_free_layout_hdr (lo); +/* Notify pnfs_destroy_layout_final() that we're done */ +if (i_state & (I_FREEING |I_CLEAR )) +wake_up_var (lo); } }
@@ -734,8 +739,7 @@ pnfs_free_lseg_list(struct list_head *free_me) } } -void -pnfs_destroy_layout (struct nfs_inode *nfsi) +static struct pnfs_layout_hdr *__pnfs_destroy_layout (struct nfs_inode *nfsi) {struct pnfs_layout_hdr *lo;LIST_HEAD (tmp_list);
@@ -753,9 +757,34 @@ pnfs_destroy_layout(struct nfs_inode *nfsi)pnfs_put_layout_hdr (lo); }else spin_unlock (&nfsi->vfs_inode.i_lock); +return lo; +} + +void pnfs_destroy_layout (struct nfs_inode *nfsi) +{ +__pnfs_destroy_layout (nfsi); }EXPORT_SYMBOL_GPL (pnfs_destroy_layout); +static bool pnfs_layout_removed (struct nfs_inode *nfsi, +struct pnfs_layout_hdr *lo) +{ +bool ret; + +spin_lock (&nfsi->vfs_inode.i_lock); + ret = nfsi->layout != lo; +spin_unlock (&nfsi->vfs_inode.i_lock); +return ret; +} + +void pnfs_destroy_layout_final (struct nfs_inode *nfsi) +{ +struct pnfs_layout_hdr *lo =__pnfs_destroy_layout (nfsi); + +if (lo) +wait_var_event (lo,pnfs_layout_removed (nfsi, lo)); +} +static bool pnfs_layout_add_bulk_destroy_list (struct inode *inode,struct list_head *layout_list)
fs/nfs/pnfs.h +5 -0
@@ -266,6 +266,7 @@ struct pnfs_layout_segment *pnfs_layout_process(struct nfs4_layoutget *lgp);void pnfs_layoutget_free (struct nfs4_layoutget *lgp);void pnfs_free_lseg_list (struct list_head *tmp_list);void pnfs_destroy_layout (struct nfs_inode *); +void pnfs_destroy_layout_final (struct nfs_inode *);void pnfs_destroy_all_layouts (struct nfs_client *); int pnfs_destroy_layouts_byfsid(struct nfs_client *clp, struct nfs_fsid *fsid,
@@ -710,6 +711,10 @@ static inline void pnfs_destroy_layout(struct nfs_inode *nfsi) { } +static inline void pnfs_destroy_layout_final (struct nfs_inode *nfsi) +{ +} +static inline struct pnfs_layout_segment *pnfs_get_lseg (struct pnfs_layout_segment *lseg) {
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 46/63 f2fs: avoid race condition for shrinker count
In reply to Greg Kroah-HartmanFrom: Jaegeuk Kim <[email protected]>
[ Upstream commit a95ba66ac1457b76fe472c8e092ab1006271f16c ]
Light reported sometimes shinker gets nat_cnt < dirty_nat_cnt resulting in wrong do_shinker work. Let's avoid to return insane overflowed value by adding single tracking value.
--- fs/f2fs/checkpoint.c | 2 +- fs/f2fs/debug.c | 11 ++++++----- fs/f2fs/f2fs.h | 10 ++++++++-- fs/f2fs/node.c | 29 ++++++++++++++++++----------- fs/f2fs/node.h | 4 ++-- fs/f2fs/shrinker.c | 4 +--- 6 files changed, 36 insertions(+), 24 deletions(-)
fs/f2fs/checkpoint.c +1 -1
@@ -1600,7 +1600,7 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) goto out; } -if (NM_I (sbi)->dirty_nat_cnt ==0 && +if (NM_I (sbi)->nat_cnt[DIRTY_NAT ] ==0 &&SIT_I (sbi)->dirty_sentries ==0 &&prefree_segments (sbi) ==0 ) {f2fs_flush_sit_entries (sbi, cpc);
fs/f2fs/debug.c +6 -5
@@ -145,8 +145,8 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->node_pages =NODE_MAPPING (sbi)->nrpages;if (sbi->meta_inode) si->meta_pages =META_MAPPING (sbi)->nrpages; - si->nats =NM_I (sbi)->nat_cnt; - si->dirty_nats =NM_I (sbi)->dirty_nat_cnt; + si->nats =NM_I (sbi)->nat_cnt[TOTAL_NAT ]; + si->dirty_nats =NM_I (sbi)->nat_cnt[DIRTY_NAT ]; si->sits =MAIN_SEGS (sbi); si->dirty_sits =SIT_I (sbi)->dirty_sentries; si->free_nids =NM_I (sbi)->nid_cnt[FREE_NID ];
@@ -278,9 +278,10 @@ static void update_mem_info(struct f2fs_sb_info *sbi) si->cache_mem += (NM_I (sbi)->nid_cnt[FREE_NID ] +NM_I (sbi)->nid_cnt[PREALLOC_NID ]) *sizeof (struct free_nid ); - si->cache_mem +=NM_I (sbi)->nat_cnt *sizeof (struct nat_entry ); - si->cache_mem +=NM_I (sbi)->dirty_nat_cnt * -sizeof (struct nat_entry_set ); + si->cache_mem +=NM_I (sbi)->nat_cnt[TOTAL_NAT ] * +sizeof (struct nat_entry ); + si->cache_mem +=NM_I (sbi)->nat_cnt[DIRTY_NAT ] * +sizeof (struct nat_entry_set ); si->cache_mem += si->inmem_pages *sizeof (struct inmem_pages );for (i =0 ; i <MAX_INO_ENTRY ; i++) si->cache_mem += sbi->im[i].ino_num *sizeof (struct ino_entry );
fs/f2fs/f2fs.h +8 -2
@@ -894,6 +894,13 @@ enum nid_state { MAX_NID_STATE, }; +enum nat_state { +TOTAL_NAT , +DIRTY_NAT , +RECLAIMABLE_NAT , +MAX_NAT_STATE , +}; +struct f2fs_nm_info {block_t nat_blkaddr;/* base disk address of NAT */ nid_t max_nid;/* maximum possible node ids */
@@ -909,8 +916,7 @@ struct f2fs_nm_info {struct rw_semaphore nat_tree_lock;/* protect nat_tree_lock */ struct list_head nat_entries;/* cached nat entry list (clean) */ spinlock_t nat_list_lock;/* protect clean nat entry list */ -unsigned int nat_cnt;/* the # of cached nat entries */ -unsigned int dirty_nat_cnt;/* total num of nat entries in set */ +unsigned int nat_cnt[MAX_NAT_STATE ];/* the # of cached nat entries */ unsigned int nat_blocks;/* # of nat blocks */ /* free node ids management */
fs/f2fs/node.c +18 -11
@@ -62,8 +62,8 @@ bool f2fs_available_free_memory(struct f2fs_sb_info *sbi, int type) sizeof(struct free_nid)) >> PAGE_SHIFT; res = mem_size < ((avail_ram * nm_i->ram_thresh /100 ) >>2 ); }else if (type ==NAT_ENTRIES ) { - mem_size = (nm_i->nat_cnt *sizeof (struct nat_entry )) >> -PAGE_SHIFT ; + mem_size = (nm_i->nat_cnt[TOTAL_NAT ] * +sizeof (struct nat_entry )) >>PAGE_SHIFT ; res = mem_size < ((avail_ram * nm_i->ram_thresh /100 ) >>2 );if (excess_cached_nats (sbi)) res = false;
@@ -177,7 +177,8 @@ static struct nat_entry *__init_nat_entry(struct f2fs_nm_info *nm_i,list_add_tail (&ne->list, &nm_i->nat_entries);spin_unlock (&nm_i->nat_list_lock); - nm_i->nat_cnt++; + nm_i->nat_cnt[TOTAL_NAT ]++; + nm_i->nat_cnt[RECLAIMABLE_NAT ]++;return ne; }
@@ -207,7 +208,8 @@ static unsigned int __gang_lookup_nat_cache(struct f2fs_nm_info *nm_i,static void __del_from_nat_cache (struct f2fs_nm_info *nm_i,struct nat_entry *e) {radix_tree_delete (&nm_i->nat_root,nat_get_nid (e)); - nm_i->nat_cnt--; + nm_i->nat_cnt[TOTAL_NAT ]--; + nm_i->nat_cnt[RECLAIMABLE_NAT ]--;__free_nat_entry (e); }
@@ -253,7 +255,8 @@ static void __set_nat_cache_dirty(struct f2fs_nm_info *nm_i,if (get_nat_flag (ne,IS_DIRTY )) goto refresh_list; - nm_i->dirty_nat_cnt++; + nm_i->nat_cnt[DIRTY_NAT ]++; + nm_i->nat_cnt[RECLAIMABLE_NAT ]--;set_nat_flag (ne,IS_DIRTY , true); refresh_list:spin_lock (&nm_i->nat_list_lock);
@@ -273,7 +276,8 @@ static void __clear_nat_cache_dirty(struct f2fs_nm_info *nm_i,set_nat_flag (ne,IS_DIRTY , false); set->entry_cnt--; - nm_i->dirty_nat_cnt--; + nm_i->nat_cnt[DIRTY_NAT ]--; + nm_i->nat_cnt[RECLAIMABLE_NAT ]++; } static unsigned int __gang_lookup_nat_set(struct f2fs_nm_info *nm_i,
@@ -2944,14 +2948,17 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)LIST_HEAD (sets);int err =0 ; -/* during unmount, let's flush nat_bits before checking dirty_nat_cnt */ +/* +* during unmount, let's flush nat_bits before checking +* nat_cnt[DIRTY_NAT]. +*/ if (enabled_nat_bits (sbi, cpc)) {down_write (&nm_i->nat_tree_lock);remove_nats_in_journal (sbi);up_write (&nm_i->nat_tree_lock); } -if (!nm_i->dirty_nat_cnt) +if (!nm_i->nat_cnt[DIRTY_NAT ])return 0 ;down_write (&nm_i->nat_tree_lock);
@@ -2962,7 +2969,8 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)* into nat entry set. */ if (enabled_nat_bits (sbi, cpc) || - !__has_cursum_space (journal, nm_i->dirty_nat_cnt,NAT_JOURNAL )) + !__has_cursum_space (journal, + nm_i->nat_cnt[DIRTY_NAT ],NAT_JOURNAL ))remove_nats_in_journal (sbi); while ((found = __gang_lookup_nat_set(nm_i,
@@ -3086,7 +3094,6 @@ static int init_node_manager(struct f2fs_sb_info *sbi)F2FS_RESERVED_NODE_NUM ; nm_i->nid_cnt[FREE_NID ] =0 ; nm_i->nid_cnt[PREALLOC_NID ] =0 ; - nm_i->nat_cnt =0 ; nm_i->ram_thresh =DEF_RAM_THRESHOLD ; nm_i->ra_nid_pages =DEF_RA_NID_PAGES ; nm_i->dirty_nats_ratio =DEF_DIRTY_NAT_RATIO_THRESHOLD ;
@@ -3220,7 +3227,7 @@ void f2fs_destroy_node_manager(struct f2fs_sb_info *sbi)__del_from_nat_cache (nm_i, natvec[idx]); } } -f2fs_bug_on (sbi, nm_i->nat_cnt); +f2fs_bug_on (sbi, nm_i->nat_cnt[TOTAL_NAT ]);/* destroy nat set cache */ nid =0 ;
fs/f2fs/node.h +2 -2
@@ -126,13 +126,13 @@ static inline void raw_nat_from_node_info(struct f2fs_nat_entry *raw_ne,static inline bool excess_dirty_nats (struct f2fs_sb_info *sbi) { -return NM_I (sbi)->dirty_nat_cnt >=NM_I (sbi)->max_nid * +return NM_I (sbi)->nat_cnt[DIRTY_NAT ] >=NM_I (sbi)->max_nid *NM_I (sbi)->dirty_nats_ratio /100 ; }static inline bool excess_cached_nats (struct f2fs_sb_info *sbi) { -return NM_I (sbi)->nat_cnt >=DEF_NAT_CACHE_THRESHOLD ; +return NM_I (sbi)->nat_cnt[TOTAL_NAT ] >=DEF_NAT_CACHE_THRESHOLD ; }static inline bool excess_dirty_nodes (struct f2fs_sb_info *sbi)
fs/f2fs/shrinker.c +1 -3
@@ -18,9 +18,7 @@ static unsigned int shrinker_run_no;static unsigned long __count_nat_entries (struct f2fs_sb_info *sbi) { -long count =NM_I (sbi)->nat_cnt -NM_I (sbi)->dirty_nat_cnt; - -return count >0 ? count :0 ; +return NM_I (sbi)->nat_cnt[RECLAIMABLE_NAT ]; }static unsigned long __count_free_nids (struct f2fs_sb_info *sbi)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 47/63 f2fs: fix race of pending_pages in decompression
In reply to Greg Kroah-HartmanFrom: Daeho Jeong <[email protected]>
[ Upstream commit 6422a71ef40e4751d59b8c9412e7e2dafe085878 ]
I found out f2fs_free_dic() is invoked in a wrong timing, but f2fs_verify_bio() still needed the dic info and it triggered the below kernel panic. It has been caused by the race condition of pending_pages value between decompression and verity logic, when the same compression cluster had been split in different bios. By split bios, f2fs_verify_bio() ended up with decreasing pending_pages value before it is reset to nr_cpages by f2fs_decompress_pages() and caused the kernel panic.
[ 4416.564763] Unable to handle kernel NULL pointer dereference
at virtual address 0000000000000000
...
[ 4416.896016] Workqueue: fsverity_read_queue f2fs_verity_work
[ 4416.908515] pc : fsverity_verify_page+0x20/0x78
[ 4416.913721] lr : f2fs_verify_bio+0x11c/0x29c
[ 4416.913722] sp : ffffffc019533cd0
[ 4416.913723] x29: ffffffc019533cd0 x28: 0000000000000402
[ 4416.913724] x27: 0000000000000001 x26: 0000000000000100
[ 4416.913726] x25: 0000000000000001 x24: 0000000000000004
[ 4416.913727] x23: 0000000000001000 x22: 0000000000000000
[ 4416.913728] x21: 0000000000000000 x20: ffffffff2076f9c0
[ 4416.913729] x19: ffffffff2076f9c0 x18: ffffff8a32380c30
[ 4416.913731] x17: ffffffc01f966d97 x16: 0000000000000298
[ 4416.913732] x15: 0000000000000000 x14: 0000000000000000
[ 4416.913733] x13: f074faec89ffffff x12: 0000000000000000
[ 4416.913734] x11: 0000000000001000 x10: 0000000000001000
[ 4416.929176] x9 : ffffffff20d1f5c7 x8 : 0000000000000000
[ 4416.929178] x7 : 626d7464ff286b6b x6 : ffffffc019533ade
[ 4416.929179] x5 : 000000008049000e x4 : ffffffff2793e9e0
[ 4416.929180] x3 : 000000008049000e x2 : ffffff89ecfa74d0
[ 4416.929181] x1 : 0000000000000c40 x0 : ffffffff2076f9c0
[ 4416.929184] Call trace:
[ 4416.929187] fsverity_verify_page+0x20/0x78
[ 4416.929189] f2fs_verify_bio+0x11c/0x29c
[ 4416.929192] f2fs_verity_work+0x58/0x84
[ 4417.050667] process_one_work+0x270/0x47c
[ 4417.055354] worker_thread+0x27c/0x4d8
[ 4417.059784] kthread+0x13c/0x320
[ 4417.063693] ret_from_fork+0x10/0x18Chao pointed this can happen by the below race condition.
Thread A f2fs_post_read_wq fsverity_wq
- f2fs_read_multi_pages()
- f2fs_alloc_dic
- dic->pending_pages = 2
- submit_bio()
- submit_bio()
- f2fs_post_read_work() handle first bio
- f2fs_decompress_work()
- __read_end_io()
- f2fs_decompress_pages()
- dic->pending_pages--
- enqueue f2fs_verity_work()
- f2fs_verity_work() handle first bio
- f2fs_verify_bio()
- dic->pending_pages--
- f2fs_post_read_work() handle second bio
- f2fs_decompress_work()
- enqueue f2fs_verity_work()
- f2fs_verify_pages()
- f2fs_free_dic()
- f2fs_verity_work() handle second bio
- f2fs_verfy_bio()
- use-after-free on dic
--- fs/f2fs/compress.c | 2 -- fs/f2fs/data.c | 58 +++++++++++++++++++++++++++++++++++++--------- fs/f2fs/f2fs.h | 1 + 3 files changed, 48 insertions(+), 13 deletions(-)
fs/f2fs/compress.c +0 -2
@@ -798,8 +798,6 @@ void f2fs_decompress_pages(struct bio *bio, struct page *page, bool verity)if (cops->destroy_decompress_ctx) cops->destroy_decompress_ctx (dic); out_free_dic: -if (verity) -atomic_set (&dic->pending_pages, dic->nr_cpages);if (!verity)f2fs_decompress_end_io (dic->rpages, dic->cluster_size, ret, false);
fs/f2fs/data.c +47 -11
115 lines not on this page · raw message
fs/f2fs/f2fs.h +1 -0
@@ -1410,6 +1410,7 @@ struct decompress_io_ctx {size_t rlen;/* valid data length in rbuf */ size_t clen;/* valid data length in cbuf */ atomic_t pending_pages;/* in-flight compressed page count */ +atomic_t verity_pages;/* in-flight page count for verity */ bool failed;/* indicate IO error during decompression */ void *private;/* payload buffer for specified decompression algorithm */ void *private2;/* extra payload buffer */
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 48/63 module: delay kobject uevent until after module init call
In reply to Greg Kroah-HartmanFrom: Jessica Yu <[email protected]>
[ Upstream commit 38dc717e97153e46375ee21797aa54777e5498f3 ]
Apparently there has been a longstanding race between udev/systemd and the module loader. Currently, the module loader sends a uevent right after sysfs initialization, but before the module calls its init function. However, some udev rules expect that the module has initialized already upon receiving the uevent.
This race has been triggered recently (see link in references) in some systemd mount unit files. For instance, the configfs module creates the /sys/kernel/config mount point in its init function, however the module loader issues the uevent before this happens. sys-kernel-config.mount expects to be able to mount /sys/kernel/config upon receipt of the module loading uevent, but if the configfs module has not called its init function yet, then this directory will not exist and the mount unit fails. A similar situation exists for sys-fs-fuse-connections.mount, as the fuse sysfs mount point is created during the fuse module's init function. If udev is faster than module initialization then the mount unit would fail in a similar fashion.
To fix this race, delay the module KOBJ_ADD uevent until after the module has finished calling its init routine.
--- kernel/module.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
kernel/module.c +3 -2
@@ -1895,7 +1895,6 @@ static int mod_sysfs_init(struct module *mod)if (err)mod_kobject_put (mod); -/* delay uevent until full sysfs population */ out:return err; }
@@ -1932,7 +1931,6 @@ static int mod_sysfs_setup(struct module *mod,add_sect_attrs (mod, info);add_notes_attrs (mod, info); -kobject_uevent (&mod->mkobj.kobj,KOBJ_ADD );return 0 ; out_unreg_modinfo_attrs:
@@ -3639,6 +3637,9 @@ static noinline int do_init_module(struct module *mod)blocking_notifier_call_chain (&module_notify_list,MODULE_STATE_LIVE , mod); +/* Delay uevent until module has finished its init routine */ +kobject_uevent (&mod->mkobj.kobj,KOBJ_ADD ); +/* * We need to finish all async code before the module init sequence * is done. This has potential to deadlock. For example, a newly
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 49/63 powerpc/64: irq replay remove decrementer overflow check
In reply to Greg Kroah-HartmanFrom: Nicholas Piggin <[email protected]>
[ Upstream commit 59d512e4374b2d8a6ad341475dc94c4a4bdec7d3 ]
This is way to catch some cases of decrementer overflow, when the decrementer has underflowed an odd number of times, while MSR[EE] was disabled.
With a typical small decrementer, a timer that fires when MSR[EE] is disabled will be "lost" if MSR[EE] remains disabled for between 4.3 and 8.6 seconds after the timer expires. In any case, the decrementer interrupt would be taken at 8.6 seconds and the timer would be found at that point.
So this check is for catching extreme latency events, and it prevents those latencies from being a further few seconds long. It's not obvious this is a good tradeoff. This is already a watchdog magnitude event and that situation is not improved a significantly with this check. For large decrementers, it's useless.
Therefore remove this check, which avoids a mftb when enabling hard disabled interrupts (e.g., when enabling after coming from hardware interrupt handlers). Perhaps more importantly, it also removes the clunky MSR[EE] vs PACA_IRQ_HARD_DIS incoherency in soft-interrupt replay which simplifies the code.
--- arch/powerpc/kernel/irq.c | 53 ++------------------------- arch/powerpc/kernel/time.c | 9 ++--- arch/powerpc/platforms/powernv/opal.c | 2 +- 3 files changed, 8 insertions(+), 56 deletions(-)
arch/powerpc/kernel/irq.c +4 -49
@@ -102,14 +102,6 @@ static inline notrace unsigned long get_irq_happened(void)return happened; } -static inline notrace int decrementer_check_overflow(void) -{ -u64 now =get_tb (); -u64 *next_tb =this_cpu_ptr (&decrementers_next_tb); - -return now >= *next_tb; -} -#ifdef CONFIG_PPC_BOOK3E /* This is called whenever we are re-enabling interrupts
@@ -142,35 +134,6 @@ notrace unsigned int __check_irq_replay(void)trace_hardirqs_on ();trace_hardirqs_off (); -/* -* We are always hard disabled here, but PACA_IRQ_HARD_DIS may -* not be set, which means interrupts have only just been hard -* disabled as part of the local_irq_restore or interrupt return -* code. In that case, skip the decrementr check becaus it's -* expensive to read the TB. -* -* HARD_DIS then gets cleared here, but it's reconciled later. -* Either local_irq_disable will replay the interrupt and that -* will reconcile state like other hard interrupts. Or interrupt -* retur will replay the interrupt and in that case it sets -* PACA_IRQ_HARD_DIS by hand (see comments in entry_64.S). -*/ -if (happened &PACA_IRQ_HARD_DIS ) { - local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS ; - -/* -* We may have missed a decrementer interrupt if hard disabled. -* Check the decrementer register in case we had a rollover -* while hard disabled. -*/ -if (!(happened &PACA_IRQ_DEC )) { -if (decrementer_check_overflow ()) { - local_paca->irq_happened |=PACA_IRQ_DEC ; - happened |=PACA_IRQ_DEC ; - } - } - } -if (happened &PACA_IRQ_DEC ) { local_paca->irq_happened &= ~PACA_IRQ_DEC ;return 0x900 ;
@@ -186,6 +149,9 @@ notrace unsigned int __check_irq_replay(void)return 0x280 ; } +if (happened &PACA_IRQ_HARD_DIS ) + local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS ; +/* There should be nothing left ! */ BUG_ON (local_paca->irq_happened !=0 );
@@ -229,18 +195,6 @@ void replay_soft_interrupts(void)if (IS_ENABLED (CONFIG_PPC_IRQ_SOFT_MASK_DEBUG ))WARN_ON_ONCE (mfmsr () &MSR_EE ); -if (happened &PACA_IRQ_HARD_DIS ) { -/* -* We may have missed a decrementer interrupt if hard disabled. -* Check the decrementer register in case we had a rollover -* while hard disabled. -*/ -if (!(happened &PACA_IRQ_DEC )) { -if (decrementer_check_overflow ()) - happened |=PACA_IRQ_DEC ; - } - } -/* * Force the delivery of pending soft-disabled interrupts on PS3. * Any HV call will have this side effect.
@@ -345,6 +299,7 @@ notrace void arch_local_irq_restore(unsigned long mask)if (IS_ENABLED (CONFIG_PPC_IRQ_SOFT_MASK_DEBUG ))WARN_ON_ONCE (!(mfmsr () &MSR_EE ));__hard_irq_disable (); + local_paca->irq_happened |=PACA_IRQ_HARD_DIS ; }else {/* * We should already be hard disabled here. We had bugs
arch/powerpc/kernel/time.c +3 -6
@@ -552,14 +552,11 @@ void timer_interrupt(struct pt_regs *regs)struct pt_regs *old_regs;u64 now; -/* Some implementations of hotplug will get timer interrupts while -* offline, just ignore these and we also need to set -* decrementers_next_tb as MAX to make sure __check_irq_replay -* don't replay timer interrupt when return, otherwise we'll trap -* here infinitely :( +/* +* Some implementations of hotplug will get timer interrupts while +* offline, just ignore these. */ if (unlikely (!cpu_online (smp_processor_id ()))) { - *next_tb = ~(u64 )0 ;set_dec (decrementer_max);return ; }
arch/powerpc/platforms/powernv/opal.c +1 -1
@@ -731,7 +731,7 @@ int opal_hmi_exception_early2(struct pt_regs *regs)return 1 ; } -/* HMI exception handler called in virtual mode during check_irq_replay. */ +/* HMI exception handler called in virtual mode when irqs are next enabled. */ int opal_handle_hmi_exception (struct pt_regs *regs) {/*
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 50/63 fs/namespace.c: WARN if mnt_count has become negative
In reply to Greg Kroah-HartmanFrom: Eric Biggers <[email protected]>
[ Upstream commit edf7ddbf1c5eb98b720b063b73e20e8a4a1ce673 ]
Missing calls to mntget() (or equivalently, too many calls to mntput()) are hard to detect because mntput() delays freeing mounts using task_work_add(), then again using call_rcu(). As a result, mnt_count can often be decremented to -1 without getting a KASAN use-after-free report. Such cases are still bugs though, and they point to real use-after-frees being possible.
For an example of this, see the bug fixed by commit 1b0b9cc8d379 ("vfs: fsmount: add missing mntget()"), discussed at
https://lkml.kernel.org/linux-fsdevel/20190605135401.GB30925@xxxxxxxxxxxxxxxxxxxxxxxxx/T/#u.
This bug *should* have been trivial to find. But actually, it wasn't found until syzkaller happened to use fchdir() to manipulate the reference count just right for the bug to be noticeable.
Address this by making mntput_no_expire() issue a WARN if mnt_count has become negative.
--- fs/namespace.c | 9 ++++++--- fs/pnode.h | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-)
fs/namespace.c +6 -3
@@ -156,10 +156,10 @@ static inline void mnt_add_count(struct mount *mnt, int n)/* * vfsmount lock must be held for write */ -unsigned int mnt_get_count (struct mount *mnt) +int mnt_get_count (struct mount *mnt) {#ifdef CONFIG_SMP -unsigned int count =0 ; +int count =0 ;int cpu;for_each_possible_cpu (cpu) {
@@ -1139,6 +1139,7 @@ static DECLARE_DELAYED_WORK(delayed_mntput_work, delayed_mntput);static void mntput_no_expire (struct mount *mnt) {LIST_HEAD (list); +int count;rcu_read_lock ();if (likely (READ_ONCE (mnt->mnt_ns))) {
@@ -1162,7 +1163,9 @@ static void mntput_no_expire(struct mount *mnt)*/ smp_mb ();mnt_add_count (mnt,-1 ); -if (mnt_get_count (mnt)) { + count =mnt_get_count (mnt); +if (count !=0 ) { +WARN_ON (count <0 );rcu_read_unlock ();unlock_mount_hash ();return ;
fs/pnode.h +1 -1
@@ -44,7 +44,7 @@ int propagate_mount_busy(struct mount *, int);void propagate_mount_unlock (struct mount *);void mnt_release_group_id (struct mount *);int get_dominating_id (struct mount *mnt,const struct path *root); -unsigned int mnt_get_count (struct mount *mnt); +int mnt_get_count (struct mount *mnt);void mnt_set_mountpoint (struct mount *,struct mountpoint *,struct mount *); void mnt_change_mountpoint(struct mount *parent, struct mountpoint *mp,
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 51/63 watchdog: rti-wdt: fix reference leak in rti_wdt_probe
In reply to Greg Kroah-HartmanFrom: Zhang Qilong <[email protected]>
[ Upstream commit 8711071e9700b67045fe5518161d63f7a03e3c9e ]
pm_runtime_get_sync() will increment pm usage counter even it failed. Forgetting to call pm_runtime_put_noidle will result in reference leak in rti_wdt_probe, so we should fix it.
--- drivers/watchdog/rti_wdt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/watchdog/rti_wdt.c +3 -1
@@ -227,8 +227,10 @@ static int rti_wdt_probe(struct platform_device *pdev)pm_runtime_enable (dev); ret =pm_runtime_get_sync (dev); -if (ret) +if (ret) { +pm_runtime_put_noidle (dev);return dev_err_probe (dev, ret,"runtime pm failed\n" ); + }platform_set_drvdata (pdev, wdt);
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 52/63 um: random: Register random as hwrng-core device
In reply to Greg Kroah-HartmanFrom: Christopher Obbard <[email protected]>
[ Upstream commit 72d3e093afae79611fa38f8f2cfab9a888fe66f2 ]
The UML random driver creates a dummy device under the guest, /dev/hw_random. When this file is read from the guest, the driver reads from the host machine's /dev/random, in-turn reading from the host kernel's entropy pool. This entropy pool could have been filled by a hardware random number generator or just the host kernel's internal software entropy generator.
Currently the driver does not fill the guests kernel entropy pool, this requires a userspace tool running inside the guest (like rng-tools) to read from the dummy device provided by this driver, which then would fill the guest's internal entropy pool.
This all seems quite pointless when we are already reading from an entropy pool, so this patch aims to register the device as a hwrng device using the hwrng-core framework. This not only improves and cleans up the driver, but also fills the guest's entropy pool without having to resort to using extra userspace tools in the guest.
This is typically a nuisance when booting a guest: the random pool takes a long time (~200s) to build up enough entropy since the dummy hwrng is not used to fill the guest's pool.
This port was originally attempted by Alexander Neville "dark" (in CC, discussion in Link), but the conversation there stalled since the handling of -EAGAIN errors were no removed and longer handled by the driver. This patch attempts to use the existing method of error handling but utilises the new hwrng core.
The issue can be noticed when booting a UML guest:
[ 2.560000] random: fast init done
[ 214.000000] random: crng init doneWith the patch applied, filling the pool becomes a lot quicker:
[ 2.560000] random: fast init done
[ 12.000000] random: crng init done--- arch/um/drivers/random.c | 101 ++++++++------------------------- drivers/char/hw_random/Kconfig | 16 +++--- 2 files changed, 33 insertions(+), 84 deletions(-)
arch/um/drivers/random.c +25 -76
@@ -11,6 +11,7 @@#include <linux/fs.h> #include <linux/interrupt.h> #include <linux/miscdevice.h> +#include <linux/hw_random.h> #include <linux/delay.h> #include <linux/uaccess.h> #include <init.h>
@@ -18,9 +19,8 @@#include <os.h> /* -* core module and version information +* core module information */ -#define RNG_VERSION "1.0.0"#define RNG_MODULE_NAME "hw_random"/* Changed at init time, in the non-modular case, and at module load
@@ -28,88 +28,36 @@* protects against a module being loaded twice at the same time. */ static int random_fd =-1 ; -static DECLARE_WAIT_QUEUE_HEAD (host_read_wait); +static struct hwrng hwrng = {0 , }; +static DECLARE_COMPLETION (have_data); -static int rng_dev_open (struct inode *inode,struct file *filp) +static int rng_dev_read (struct hwrng *rng,void *buf,size_t max,bool block) { -/* enforce read-only access to this chrdev */ -if ((filp->f_mode &FMODE_READ ) ==0 ) -return -EINVAL ; -if ((filp->f_mode &FMODE_WRITE ) !=0 ) -return -EINVAL ; +int ret; -return 0 ; -} - -static atomic_t host_sleep_count =ATOMIC_INIT (0 ); - -static ssize_t rng_dev_read (struct file *filp,char __user *buf,size_t size, -loff_t *offp) -{ -u32 data; -int n, ret =0 , have_data; - -while (size) { - n =os_read_file (random_fd, &data,sizeof (data)); -if (n >0 ) { - have_data = n; -while (have_data && size) { -if (put_user ((u8 ) data, buf++)) { - ret = ret ? : -EFAULT ; -break ; - } - size--; - ret++; - have_data--; - data >>=8 ; - } - } -else if (n == -EAGAIN ) { -DECLARE_WAITQUEUE (wait, current); - -if (filp->f_flags &O_NONBLOCK ) -return ret ? : -EAGAIN ; - -atomic_inc (&host_sleep_count); +for (;;) { + ret =os_read_file (random_fd, buf, max); +if (block && ret == -EAGAIN ) {add_sigio_fd (random_fd); -add_wait_queue (&host_read_wait, &wait); -set_current_state (TASK_INTERRUPTIBLE ); + ret =wait_for_completion_killable (&have_data); -schedule (); -remove_wait_queue (&host_read_wait, &wait); +ignore_sigio_fd (random_fd); +deactivate_fd (random_fd,RANDOM_IRQ ); -if (atomic_dec_and_test (&host_sleep_count)) { -ignore_sigio_fd (random_fd); -deactivate_fd (random_fd,RANDOM_IRQ ); - } +if (ret <0 ) +break ; + }else { +break ; } -else -return n; - -if (signal_pending (current)) -return ret ? : -ERESTARTSYS ; } -return ret; -} -static const struct file_operations rng_chrdev_ops = { - .owner =THIS_MODULE , - .open = rng_dev_open, - .read = rng_dev_read, - .llseek = noop_llseek, -}; - -/* rng_init shouldn't be called more than once at boot time */ -static struct miscdevice rng_miscdev = { -HWRNG_MINOR , -RNG_MODULE_NAME , - &rng_chrdev_ops, -}; +return ret != -EAGAIN ? ret :0 ; +}static irqreturn_t random_interrupt (int irq,void *data) { -wake_up (&host_read_wait); +complete (&have_data);return IRQ_HANDLED ; }
@@ -126,18 +74,19 @@ static int __init rng_init (void) goto out; random_fd = err; - err =um_request_irq (RANDOM_IRQ , random_fd,IRQ_READ , random_interrupt,0 ,"random" ,NULL );if (err) goto err_out_cleanup_hw;sigio_broken (random_fd,1 ); + hwrng.name =RNG_MODULE_NAME ; + hwrng.read = rng_dev_read; + hwrng.quality =1024 ; - err =misc_register (&rng_miscdev); + err =hwrng_register (&hwrng);if (err) { - printk (KERN_ERR RNG_MODULE_NAME ": misc device register " - "failed\n"); +pr_err (RNG_MODULE_NAME " registering failed (%d)\n" , err); goto err_out_cleanup_hw; } out:
@@ -161,8 +110,8 @@ static void cleanup(void) static void __exit rng_cleanup(void) { +hwrng_unregister (&hwrng);os_close_file (random_fd); -misc_deregister (&rng_miscdev); }module_init (rng_init);
drivers/char/hw_random/Kconfig +8 -8
@@ -540,15 +540,15 @@ endif # HW_RANDOM config UML_RANDOM depends on UML - tristate "Hardware random number generator" + select HW_RANDOM + tristate "UML Random Number Generator support" help This option enables UML's "hardware" random number generator. It attaches itself to the host's /dev/random, supplying as much entropy as the host has, rather than the small amount the UML gets from its - own drivers. It registers itself as a standard hardware random number - generator, major 10, minor 183, and the canonical device name is - /dev/hwrng. - The way to make use of this is to install the rng-tools package - (check your distro, or download from - http://sourceforge.net/projects/gkernel/). rngd periodically reads - /dev/hwrng and injects the entropy into /dev/random. + own drivers. It registers itself as a rng-core driver thus providing + a device which is usually called /dev/hwrng. This hardware random + number generator does feed into the kernel's random number generator + entropy pool. + + If unsure, say Y.
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 53/63 um: ubd: Submit all data segments atomically
In reply to Greg Kroah-HartmanFrom: Gabriel Krisman Bertazi <[email protected]>
[ Upstream commit fc6b6a872dcd48c6f39c7975836d75113db67d37 ]
Internally, UBD treats each physical IO segment as a separate command to be submitted in the execution pipe. If the pipe returns a transient error after a few segments have already been written, UBD will tell the block layer to requeue the request, but there is no way to reclaim the segments already submitted. When a new attempt to dispatch the request is done, those segments already submitted will get duplicated, causing the WARN_ON below in the best case, and potentially data corruption.
In my system, running a UML instance with 2GB of RAM and a 50M UBD disk, I can reproduce the WARN_ON by simply running mkfs.fvat against the disk on a freshly booted system.
There are a few ways to around this, like reducing the pressure on the pipe by reducing the queue depth, which almost eliminates the occurrence of the problem, increasing the pipe buffer size on the host system, or by limiting the request to one physical segment, which causes the block layer to submit way more requests to resolve a single operation.
Instead, this patch modifies the format of a UBD command, such that all segments are sent through a single element in the communication pipe, turning the command submission atomic from the point of view of the block layer. The new format has a variable size, depending on the number of elements, and looks like this:
+------------+-----------+-----------+------------ | cmd_header | segment 0 | segment 1 | segment ... +------------+-----------+-----------+------------
With this format, we push a pointer to cmd_header in the submission pipe.
This has the advantage of reducing the memory footprint of executing a single request, since it allow us to merge some fields in the header. It is possible to reduce even further each segment memory footprint, by merging bitmap_words and cow_offset, for instance, but this is not the focus of this patch and is left as future work. One issue with the patch is that for a big number of segments, we now perform one big memory allocation instead of multiple small ones, but I wasn't able to trigger any real issues or -ENOMEM because of this change, that wouldn't be reproduced otherwise.
This was tested using fio with the verify-crc32 option, and by running an ext4 filesystem over this UBD device.
The original WARN_ON was:
------------[ cut here ]------------ WARNING: CPU: 0 PID: 0 at lib/refcount.c:28 refcount_warn_saturate+0x13f/0x141 refcount_t: underflow; use-after-free. Modules linked in: CPU: 0 PID: 0 Comm: swapper Not tainted 5.5.0-rc6-00002-g2a5bb2cf75c8 #346 Stack: 6084eed0 6063dc77 00000009 6084ef60 00000000 604b8d9f 6084eee0 6063dcbc 6084ef40 6006ab8d e013d780 1c00000000 Call Trace: [<600a0c1c>] ? printk+0x0/0x94 [<6004a888>] show_stack+0x13b/0x155 [<6063dc77>] ? dump_stack_print_info+0xdf/0xe8 [<604b8d9f>] ? refcount_warn_saturate+0x13f/0x141 [<6063dcbc>] dump_stack+0x2a/0x2c [<6006ab8d>] __warn+0x107/0x134 [<6008da6c>] ? wake_up_process+0x17/0x19 [<60487628>] ? blk_queue_max_discard_sectors+0x0/0xd [<6006b05f>] warn_slowpath_fmt+0xd1/0xdf [<6006af8e>] ? warn_slowpath_fmt+0x0/0xdf [<600acc14>] ? raw_read_seqcount_begin.constprop.0+0x0/0x15 [<600619ae>] ? os_nsecs+0x1d/0x2b [<604b8d9f>] refcount_warn_saturate+0x13f/0x141 [<6048bc8f>] refcount_sub_and_test.constprop.0+0x2f/0x37 [<6048c8de>] blk_mq_free_request+0xf1/0x10d [<6048ca06>] __blk_mq_end_request+0x10c/0x114 [<6005ac0f>] ubd_intr+0xb5/0x169 [<600a1a37>] __handle_irq_event_percpu+0x6b/0x17e [<600a1b70>] handle_irq_event_percpu+0x26/0x69 [<600a1bd9>] handle_irq_event+0x26/0x34 [<600a1bb3>] ? handle_irq_event+0x0/0x34 [<600a5186>] ? unmask_irq+0x0/0x37 [<600a57e6>] handle_edge_irq+0xbc/0xd6 [<600a131a>] generic_handle_irq+0x21/0x29 [<60048f6e>] do_IRQ+0x39/0x54 [...] ---[ end trace c6e7444e55386c0f ]---
--- arch/um/drivers/ubd_kern.c | 191 ++++++++++++++++++++++--------------- 1 file changed, 115 insertions(+), 76 deletions(-)
arch/um/drivers/ubd_kern.c +115 -76
@@ -47,18 +47,25 @@/* Max request size is determined by sector mask - 32K */ #define UBD_MAX_REQUEST (8 * sizeof(long)) +struct io_desc { +char *buffer; +unsigned long length; +unsigned long sector_mask; +unsigned long long cow_offset; +unsigned long bitmap_words[2 ]; +}; +struct io_thread_req {struct request *req;int fds[2 ];unsigned long offsets[2 ];unsigned long long offset; -unsigned long length; -char *buffer;int sectorsize; -unsigned long sector_mask; -unsigned long long cow_offset; -unsigned long bitmap_words[2 ];int error; + +int desc_cnt; +/* io_desc has to be the last element of the struct */ +struct io_desc io_desc[]; };
@@ -525,12 +532,7 @@ static void ubd_handler(void)blk_queue_max_write_zeroes_sectors (io_req->req->q,0 );blk_queue_flag_clear (QUEUE_FLAG_DISCARD , io_req->req->q); } -if ((io_req->error) || (io_req->buffer ==NULL )) -blk_mq_end_request (io_req->req, io_req->error); -else { -if (!blk_update_request (io_req->req, io_req->error, io_req->length)) -__blk_mq_end_request (io_req->req, io_req->error); - } +blk_mq_end_request (io_req->req, io_req->error);kfree (io_req); } }
@@ -946,6 +948,7 @@ static int ubd_add(int n, char **error_out)blk_queue_write_cache (ubd_dev->queue, true, false);blk_queue_max_segments (ubd_dev->queue,MAX_SG ); +blk_queue_segment_boundary (ubd_dev->queue,PAGE_SIZE -1 ); err =ubd_disk_register (UBD_MAJOR , ubd_dev->size, n, &ubd_gendisk[n]);if (err){ *error_out ="Failed to register device" ;
@@ -1289,37 +1292,74 @@ static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, *cow_offset += bitmap_offset; } -static void cowify_req (struct io_thread_req *req,unsigned long *bitmap, +static void cowify_req (struct io_thread_req *req,struct io_desc *segment, +unsigned long offset,unsigned long *bitmap,__u64 bitmap_offset,__u64 bitmap_len) { -__u64 sector = req->offset >>SECTOR_SHIFT ; +__u64 sector = offset >>SECTOR_SHIFT ;int i; -if (req->length > (sizeof (req->sector_mask) *8 ) <<SECTOR_SHIFT ) +if (segment->length > (sizeof (segment->sector_mask) *8 ) <<SECTOR_SHIFT )panic ("Operation too long" );if (req_op (req->req) ==REQ_OP_READ ) { -for (i =0 ; i < req->length >>SECTOR_SHIFT ; i++) { +for (i =0 ; i < segment->length >>SECTOR_SHIFT ; i++) {if (ubd_test_bit (sector + i, (unsigned char *) bitmap))ubd_set_bit (i, (unsigned char *) - &req->sector_mask); + &segment->sector_mask); + } + }else { +cowify_bitmap (offset, segment->length, &segment->sector_mask, + &segment->cow_offset, bitmap, bitmap_offset, + segment->bitmap_words, bitmap_len); + } +} + +static void ubd_map_req (struct ubd *dev,struct io_thread_req *io_req, +struct request *req) +{ +struct bio_vec bvec; +struct req_iterator iter; +int i =0 ; +unsigned long byte_offset = io_req->offset; +int op =req_op (req); + +if (op ==REQ_OP_WRITE_ZEROES || op ==REQ_OP_DISCARD ) { + io_req->io_desc[0 ].buffer =NULL ; + io_req->io_desc[0 ].length =blk_rq_bytes (req); + }else { +rq_for_each_segment (bvec, req, iter) { +BUG_ON (i >= io_req->desc_cnt); + + io_req->io_desc[i].buffer = +page_address (bvec.bv_page) + bvec.bv_offset; + io_req->io_desc[i].length = bvec.bv_len; + i++; + } + } + +if (dev->cow.file) { +for (i =0 ; i < io_req->desc_cnt; i++) { +cowify_req (io_req, &io_req->io_desc[i], byte_offset, + dev->cow.bitmap, dev->cow.bitmap_offset, + dev->cow.bitmap_len); + byte_offset += io_req->io_desc[i].length; } + } -else cowify_bitmap (req->offset, req->length, &req->sector_mask, - &req->cow_offset, bitmap, bitmap_offset, - req->bitmap_words, bitmap_len); } -static int ubd_queue_one_vec (struct blk_mq_hw_ctx *hctx,struct request *req, -u64 off,struct bio_vec *bvec) +static struct io_thread_req *ubd_alloc_req (struct ubd *dev,struct request *req, +int desc_cnt) { -struct ubd *dev = hctx->queue->queuedata;struct io_thread_req *io_req; -int ret; +int i; - io_req =kmalloc (sizeof (struct io_thread_req ),GFP_ATOMIC ); + io_req =kmalloc (sizeof (*io_req) + + (desc_cnt *sizeof (struct io_desc )), +GFP_ATOMIC );if (!io_req) -return -ENOMEM ; +return NULL ; io_req->req = req;if (dev->cow.file)
@@ -1327,26 +1367,41 @@ static int ubd_queue_one_vec(struct blk_mq_hw_ctx *hctx, struct request *req,else io_req->fds[0 ] = dev->fd; io_req->error =0 ; - -if (bvec !=NULL ) { - io_req->buffer =page_address (bvec->bv_page) + bvec->bv_offset; - io_req->length = bvec->bv_len; - }else { - io_req->buffer =NULL ; - io_req->length =blk_rq_bytes (req); - } - io_req->sectorsize =SECTOR_SIZE ; io_req->fds[1 ] = dev->fd; - io_req->cow_offset =-1 ; - io_req->offset = off; - io_req->sector_mask =0 ; + io_req->offset = (u64 )blk_rq_pos (req) <<SECTOR_SHIFT ; io_req->offsets[0 ] =0 ; io_req->offsets[1 ] = dev->cow.data_offset; -if (dev->cow.file) -cowify_req (io_req, dev->cow.bitmap, - dev->cow.bitmap_offset, dev->cow.bitmap_len); +for (i =0 ; i < desc_cnt; i++) { + io_req->io_desc[i].sector_mask =0 ; + io_req->io_desc[i].cow_offset =-1 ; + } + +return io_req; +} + +static int ubd_submit_request (struct ubd *dev,struct request *req) +{ +int segs =0 ; +struct io_thread_req *io_req; +int ret; +int op =req_op (req); + +if (op ==REQ_OP_FLUSH ) + segs =0 ; +else if (op ==REQ_OP_WRITE_ZEROES || op ==REQ_OP_DISCARD ) + segs =1 ; +else + segs =blk_rq_nr_phys_segments (req); + + io_req =ubd_alloc_req (dev, req, segs); +if (!io_req) +return -ENOMEM ; + + io_req->desc_cnt = segs; +if (segs) +ubd_map_req (dev, io_req, req); ret =os_write_file (thread_fd, &io_req,sizeof (io_req));if (ret !=sizeof (io_req)) {
@@ -1357,22 +1412,6 @@ static int ubd_queue_one_vec(struct blk_mq_hw_ctx *hctx, struct request *req,return ret; } -static int queue_rw_req (struct blk_mq_hw_ctx *hctx,struct request *req) -{ -struct req_iterator iter; -struct bio_vec bvec; -int ret; -u64 off = (u64 )blk_rq_pos (req) <<SECTOR_SHIFT ; - -rq_for_each_segment (bvec, req, iter) { - ret =ubd_queue_one_vec (hctx, req, off, &bvec); -if (ret <0 ) -return ret; - off += bvec.bv_len; - } -return 0 ; -} -static blk_status_t ubd_queue_rq (struct blk_mq_hw_ctx *hctx,const struct blk_mq_queue_data *bd) {
@@ -1385,17 +1424,12 @@ static blk_status_t ubd_queue_rq(struct blk_mq_hw_ctx *hctx,spin_lock_irq (&ubd_dev->lock);switch (req_op (req)) { -/* operations with no lentgth/offset arguments */ case REQ_OP_FLUSH : - ret =ubd_queue_one_vec (hctx, req,0 ,NULL ); -break ;case REQ_OP_READ :case REQ_OP_WRITE : - ret =queue_rw_req (hctx, req); -break ;case REQ_OP_DISCARD :case REQ_OP_WRITE_ZEROES : - ret =ubd_queue_one_vec (hctx, req, (u64 )blk_rq_pos (req) <<9 ,NULL ); + ret =ubd_submit_request (ubd_dev, req);break ;default :WARN_ON_ONCE (1 );
@@ -1483,22 +1517,22 @@ static int map_error(int error_code)* will result in unpredictable behaviour and/or crashes. */ -static int update_bitmap (struct io_thread_req *req) +static int update_bitmap (struct io_thread_req *req,struct io_desc *segment) {int n; -if (req->cow_offset ==-1 ) +if (segment->cow_offset ==-1 )return map_error (0 ); - n =os_pwrite_file (req->fds[1 ], &req->bitmap_words, -sizeof (req->bitmap_words), req->cow_offset); -if (n !=sizeof (req->bitmap_words)) + n =os_pwrite_file (req->fds[1 ], &segment->bitmap_words, +sizeof (segment->bitmap_words), segment->cow_offset); +if (n !=sizeof (segment->bitmap_words))return map_error (-n);return map_error (0 ); } -static void do_io (struct io_thread_req *req) +static void do_io (struct io_thread_req *req,struct io_desc *desc) {char *buf =NULL ;unsigned long len;
@@ -1513,21 +1547,20 @@ static void do_io(struct io_thread_req *req)return ; } - nsectors = req->length / req->sectorsize; + nsectors = desc->length / req->sectorsize; start =0 ; do { - bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask); + bit = ubd_test_bit(start, (unsigned char *) &desc->sector_mask); end = start; while((end < nsectors) && - (ubd_test_bit(end, (unsigned char *) - &req->sector_mask) == bit)) + (ubd_test_bit(end, (unsigned char *) &desc->sector_mask) == bit)) end++; off = req->offset + req->offsets[bit] + start * req->sectorsize; len = (end - start) * req->sectorsize; - if (req->buffer != NULL) - buf = &req->buffer[start * req->sectorsize]; + if (desc->buffer != NULL) + buf = &desc->buffer[start * req->sectorsize]; switch (req_op(req->req)) { case REQ_OP_READ:
@@ -1567,7 +1600,8 @@ static void do_io(struct io_thread_req *req) start = end; }while (start < nsectors); - req->error =update_bitmap (req); + req->offset += len; + req->error =update_bitmap (req, desc); }/* Changed in start_io_thread, which is serialized by being called only
@@ -1600,8 +1634,13 @@ int io_thread(void *arg) }for (count =0 ; count < n/sizeof (struct io_thread_req *); count++) { +struct io_thread_req *req = (*io_req_buffer)[count]; +int i; + io_count++; -do_io ((*io_req_buffer)[count]); +for (i =0 ; !req->error && i < req->desc_cnt; i++) +do_io (req, &(req->io_desc[i])); + } written =0 ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 54/63 NFSv4.2: Dont error when exiting early on a READ_PLUS buffer overflow
In reply to Greg Kroah-HartmanFrom: Trond Myklebust <[email protected]>
[ Upstream commit 503b934a752f7e789a5f33217520e0a79f3096ac ]
Expanding the READ_PLUS extents can cause the read buffer to overflow. If it does, then don't error, but just exit early.
--- fs/nfs/nfs42xdr.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-)
fs/nfs/nfs42xdr.c +17 -19
@@ -1019,29 +1019,24 @@ static int decode_deallocate(struct xdr_stream *xdr, struct nfs42_falloc_res *rereturn decode_op_hdr (xdr,OP_DEALLOCATE ); } -static int decode_read_plus_data (struct xdr_stream *xdr,struct nfs_pgio_res *res, -uint32_t *eof) +static int decode_read_plus_data (struct xdr_stream *xdr, +struct nfs_pgio_res *res) {uint32_t count, recvd;uint64_t offset;__be32 *p; p =xdr_inline_decode (xdr,8 +4 ); -if (unlikely (!p)) -return -EIO ; +if (!p) +return 1 ; p =xdr_decode_hyper (p, &offset); count =be32_to_cpup (p); recvd =xdr_align_data (xdr, res->count, count); res->count += recvd; -if (count > recvd) { -dprintk ("NFS: server cheating in read reply: " -"count %u > recvd %u\n" , count, recvd); - *eof =0 ; +if (count > recvd)return 1 ; - } -return 0 ; }
@@ -1052,18 +1047,16 @@ static int decode_read_plus_hole(struct xdr_stream *xdr, struct nfs_pgio_res *re__be32 *p; p =xdr_inline_decode (xdr,8 +8 ); -if (unlikely (!p)) -return -EIO ; +if (!p) +return 1 ; p =xdr_decode_hyper (p, &offset); p =xdr_decode_hyper (p, &length); recvd =xdr_expand_hole (xdr, res->count, length); res->count += recvd; -if (recvd < length) { - *eof =0 ; +if (recvd < length)return 1 ; - }return 0 ; }
@@ -1088,12 +1081,12 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)for (i =0 ; i < segments; i++) { p =xdr_inline_decode (xdr,4 ); -if (unlikely (!p)) -return -EIO ; +if (!p) + goto early_out; type =be32_to_cpup (p++);if (type ==NFS4_CONTENT_DATA ) - status =decode_read_plus_data (xdr, res, &eof); + status =decode_read_plus_data (xdr, res);else if (type ==NFS4_CONTENT_HOLE ) status =decode_read_plus_hole (xdr, res, &eof);else
@@ -1102,12 +1095,17 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)if (status <0 )return status;if (status >0 ) -break ; + goto early_out; } out: res->eof = eof;return 0 ; +early_out: +if (unlikely (!i)) +return -EIO ; + res->eof =0 ; +return 0 ; }static int decode_seek (struct xdr_stream *xdr,struct nfs42_seek_res *res)
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 55/63 ceph: fix inode refcount leak when ceph_fill_inode on non-I_NEW inode fails
In reply to Greg Kroah-HartmanFrom: Jeff Layton <[email protected]>
[ Upstream commit 68cbb8056a4c24c6a38ad2b79e0a9764b235e8fa ]
--- fs/ceph/inode.c | 2 ++ 1 file changed, 2 insertions(+)
fs/ceph/inode.c +2 -0
@@ -1335,6 +1335,8 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req) in, ceph_vinop(in));if (in->i_state &I_NEW )discard_new_inode (in); +else +iput (in); goto done; } req->r_target_inode = in;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 56/63 drm/amd/display: updated wm table for Renoir
In reply to Greg Kroah-HartmanFrom: Jake Wang <[email protected]>
[ Upstream commit 410066d24cfc1071be25e402510367aca9db5cb6 ]
[Why]
For certain timings, Renoir may underflow due to sr exit latency being too slow.
[How]
Updated wm table for renoir.
--- .../drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +6 -6
@@ -704,24 +704,24 @@ static struct wm_table ddr4_wm_table_rn = { .wm_inst = WM_B, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.72, - .sr_exit_time_us = 10.12, - .sr_enter_plus_exit_time_us = 11.48, + .sr_exit_time_us = 11.12, + .sr_enter_plus_exit_time_us = 12.48, .valid = true, }, { .wm_inst = WM_C, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.72, - .sr_exit_time_us = 10.12, - .sr_enter_plus_exit_time_us = 11.48, + .sr_exit_time_us = 11.12, + .sr_enter_plus_exit_time_us = 12.48, .valid = true, }, { .wm_inst = WM_D, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.72, - .sr_exit_time_us = 10.12, - .sr_enter_plus_exit_time_us = 11.48, + .sr_exit_time_us = 11.12, + .sr_enter_plus_exit_time_us = 12.48, .valid = true, }, }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 57/63 tick/sched: Remove bogus boot "safety" check
In reply to Greg Kroah-HartmanFrom: Thomas Gleixner <[email protected]>
[ Upstream commit ba8ea8e7dd6e1662e34e730eadfc52aa6816f9dd ]
can_stop_idle_tick() checks whether the do_timer() duty has been taken over by a CPU on boot. That's silly because the boot CPU always takes over with the initial clockevent device.
But even if no CPU would have installed a clockevent and taken over the duty then the question whether the tick on the current CPU can be stopped or not is moot. In that case the current CPU would have no clockevent either, so there would be nothing to keep ticking.
Remove it.
--- kernel/time/tick-sched.c | 7 ------- 1 file changed, 7 deletions(-)
kernel/time/tick-sched.c +0 -7
@@ -941,13 +941,6 @@ static bool can_stop_idle_tick(int cpu, struct tick_sched *ts)*/ if (tick_do_timer_cpu == cpu)return false; -/* -* Boot safety: make sure the timekeeping duty has been -* assigned before entering dyntick-idle mode, -* tick_do_timer_cpu is TICK_DO_TIMER_BOOT -*/ -if (unlikely (tick_do_timer_cpu ==TICK_DO_TIMER_BOOT )) -return false;/* Should not happen for nohz-full */ if (WARN_ON_ONCE (tick_do_timer_cpu ==TICK_DO_TIMER_NONE ))
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 58/63 s390: always clear kernel stack backchain before calling functions
In reply to Greg Kroah-HartmanFrom: Heiko Carstens <[email protected]>
[ Upstream commit 9365965db0c7ca7fc81eee27c21d8522d7102c32 ]
Clear the kernel stack backchain before potentially calling the lockdep trace_hardirqs_off/on functions. Without this walking the kernel backchain, e.g. during a panic, might stop too early.
--- arch/s390/kernel/entry.S | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
arch/s390/kernel/entry.S +6 -6
@@ -406,6 +406,7 @@ ENTRY(system_call) mvc __PT_PSW(16,%r11),__LC_SVC_OLD_PSW mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC stg %r14,__PT_FLAGS(%r11) + xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) ENABLE_INTS .Lsysc_do_svc: # clear user controlled register to prevent speculative use
@@ -422,7 +423,6 @@ ENTRY(system_call) jnl .Lsysc_nr_ok slag %r8,%r1,3 .Lsysc_nr_ok: - xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) stg %r2,__PT_ORIG_GPR2(%r11) stg %r7,STACK_FRAME_OVERHEAD(%r15) lg %r9,0(%r8,%r10) # get system call add.
@@ -712,8 +712,8 @@ ENTRY(pgm_check_handler) mvc __THREAD_per_address(8,%r14),__LC_PER_ADDRESS mvc __THREAD_per_cause(2,%r14),__LC_PER_CODE mvc __THREAD_per_paid(1,%r14),__LC_PER_ACCESS_ID -6: RESTORE_SM_CLEAR_PER - xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) +6: xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) + RESTORE_SM_CLEAR_PER larl %r1,pgm_check_table llgh %r10,__PT_INT_CODE+2(%r11) nill %r10,0x007f
@@ -734,8 +734,8 @@ ENTRY(pgm_check_handler) # PER event in supervisor state, must be kprobes # .Lpgm_kprobe: - RESTORE_SM_CLEAR_PER xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) + RESTORE_SM_CLEAR_PER lgr %r2,%r11 # pass pointer to pt_regs brasl %r14,do_per_trap j .Lpgm_return
@@ -777,10 +777,10 @@ ENTRY(io_int_handler) stmg %r8,%r9,__PT_PSW(%r11) mvc __PT_INT_CODE(12,%r11),__LC_SUBCHANNEL_ID xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) + xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) TSTMSK __LC_CPU_FLAGS,_CIF_IGNORE_IRQ jo .Lio_restore TRACE_IRQS_OFF - xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) .Lio_loop: lgr %r2,%r11 # pass pointer to pt_regs lghi %r3,IO_INTERRUPT
@@ -980,10 +980,10 @@ ENTRY(ext_int_handler) mvc __PT_INT_PARM(4,%r11),__LC_EXT_PARAMS mvc __PT_INT_PARM_LONG(8,%r11),0(%r1) xc __PT_FLAGS(8,%r11),__PT_FLAGS(%r11) + xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) TSTMSK __LC_CPU_FLAGS,_CIF_IGNORE_IRQ jo .Lio_restore TRACE_IRQS_OFF - xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) lgr %r2,%r11 # pass pointer to pt_regs lghi %r3,EXT_INTERRUPT brasl %r14,do_IRQ
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 59/63 io_uring: remove racy overflow list fast checks
In reply to Greg Kroah-HartmanFrom: Pavel Begunkov <[email protected]>
[ Upstream commit 9cd2be519d05ee78876d55e8e902b7125f78b74f ]
list_empty_careful() is not racy only if some conditions are met, i.e. no re-adds after del_init. io_cqring_overflow_flush() does list_move(), so it's actually racy.
Remove those checks, we have ->cq_check_overflow for the fast path.
--- fs/io_uring.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
fs/io_uring.c +1 -4
@@ -1636,8 +1636,6 @@ static bool io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force,LIST_HEAD (list);if (!force) { -if (list_empty_careful (&ctx->cq_overflow_list)) -return true;if ((ctx->cached_cq_tail -READ_ONCE (rings->cq.head) == rings->cq_ring_entries))return false;
@@ -6579,8 +6577,7 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr)/* if we have a backlog and couldn't flush it all, return BUSY */ if (test_bit (0 , &ctx->sq_check_overflow)) { -if (!list_empty (&ctx->cq_overflow_list) && - !io_cqring_overflow_flush (ctx, false,NULL ,NULL )) +if (!io_cqring_overflow_flush (ctx, false,NULL ,NULL ))return -EBUSY ; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 60/63 ALSA: pcm: Clear the full allocated memory at hw_params
In reply to Greg Kroah-HartmanFrom: Takashi Iwai <[email protected]>
[ Upstream commit 618de0f4ef11acd8cf26902e65493d46cc20cc89 ]
The PCM hw_params core function tries to clear up the PCM buffer before actually using for avoiding the information leak from the previous usages or the usage before a new allocation. It performs the memset() with runtime->dma_bytes, but this might still leave some remaining bytes untouched; namely, the PCM buffer size is aligned in page size for mmap, hence runtime->dma_bytes doesn't necessarily cover all PCM buffer pages, and the remaining bytes are exposed via mmap.
This patch changes the memory clearance to cover the all buffer pages if the stream is supposed to be mmap-ready (that guarantees that the buffer size is aligned in page size).
--- sound/core/pcm_native.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
sound/core/pcm_native.c +7 -2
@@ -755,8 +755,13 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, runtime->boundary *=2 ;/* clear the buffer for avoiding possible kernel info leaks */ -if (runtime->dma_area && !substream->ops->copy_user) -memset (runtime->dma_area,0 , runtime->dma_bytes); +if (runtime->dma_area && !substream->ops->copy_user) { +size_t size = runtime->dma_bytes; + +if (runtime->info &SNDRV_PCM_INFO_MMAP ) + size =PAGE_ALIGN (size); +memset (runtime->dma_area,0 , size); + }snd_pcm_timer_resolution_change (substream);snd_pcm_set_state (substream,SNDRV_PCM_STATE_SETUP );
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 61/63 dm verity: skip verity work if I/O error when system is shutting down
In reply to Greg Kroah-HartmanFrom: Hyeongseok Kim <[email protected]>
[ Upstream commit 252bd1256396cebc6fc3526127fdb0b317601318 ]
If emergency system shutdown is called, like by thermal shutdown, a dm device could be alive when the block device couldn't process I/O requests anymore. In this state, the handling of I/O errors by new dm I/O requests or by those already in-flight can lead to a verity corruption state, which is a misjudgment.
So, skip verity work in response to I/O error when system is shutting down.
--- drivers/md/dm-verity-target.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/md/dm-verity-target.c +11 -1
@@ -537,6 +537,15 @@ static int verity_verify_io(struct dm_verity_io *io)return 0 ; } +/* +* Skip verity work in response to I/O error when system is shutting down. +*/ +static inline bool verity_is_system_shutting_down (void ) +{ +return system_state ==SYSTEM_HALT || system_state ==SYSTEM_POWER_OFF + || system_state ==SYSTEM_RESTART ; +} +/* * End one "io" structure with a given error. */
@@ -564,7 +573,8 @@ static void verity_end_io(struct bio *bio) {struct dm_verity_io *io = bio->bi_private; -if (bio->bi_status && !verity_fec_is_enabled (io->v)) { +if (bio->bi_status && + (!verity_fec_is_enabled (io->v) ||verity_is_system_shutting_down ())) {verity_finish_io (io, bio->bi_status);return ; }
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 62/63 ext4: avoid s_mb_prefetch to be zero in individual scenarios
In reply to Greg Kroah-HartmanFrom: Chunguang Xu <[email protected]>
[ Upstream commit 82ef1370b0c1757ab4ce29f34c52b4e93839b0aa ]
Commit cfd732377221 ("ext4: add prefetching for block allocation bitmaps") introduced block bitmap prefetch, and expects to read block bitmaps of flex_bg through an IO. However, it seems to ignore the value range of s_log_groups_per_flex. In the scenario where the value of s_log_groups_per_flex is greater than 27, s_mb_prefetch or s_mb_prefetch_limit will overflow, cause a divide zero exception.
In addition, the logic of calculating nr is also flawed, because the size of flexbg is fixed during a single mount, but s_mb_prefetch can be modified, which causes nr to fail to meet the value condition of [1, flexbg_size].
To solve this problem, we need to set the upper limit of s_mb_prefetch. Since we expect to load block bitmaps of a flex_bg through an IO, we can consider determining a reasonable upper limit among the IO limit parameters. After consideration, we chose BLK_MAX_SEGMENT_SIZE. This is a good choice to solve divide zero problem and avoiding performance degradation.
[ Some minor code simplifications to make the changes easy to follow -- TYT ]
--- fs/ext4/mballoc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
fs/ext4/mballoc.c +5 -4
@@ -2395,9 +2395,9 @@ ext4_mb_regular_allocator(struct ext4_allocation_context *ac) nr = sbi->s_mb_prefetch;if (ext4_has_feature_flex_bg (sb)) { - nr = (group / sbi->s_mb_prefetch) * - sbi->s_mb_prefetch; - nr = nr + sbi->s_mb_prefetch - group; + nr =1 << sbi->s_log_groups_per_flex; + nr -= group & (nr -1 ); + nr =min (nr, sbi->s_mb_prefetch); } prefetch_grp =ext4_mb_prefetch (sb, group, nr, &prefetch_ios);
@@ -2733,7 +2733,8 @@ static int ext4_mb_init_backend(struct super_block *sb)if (ext4_has_feature_flex_bg (sb)) {/* a single flex group is supposed to be read by a single IO */ - sbi->s_mb_prefetch =1 << sbi->s_es->s_log_groups_per_flex; + sbi->s_mb_prefetch =min (1 << sbi->s_es->s_log_groups_per_flex, +BLK_MAX_SEGMENT_SIZE >> (sb->s_blocksize_bits -9 )); sbi->s_mb_prefetch *=8 ;/* 8 prefetch IOs in flight at most */ }else { sbi->s_mb_prefetch =32 ;
Signature · 1 line
2.27.0
Greg Kroah-Hartman
maintainerPATCH 63/63 device-dax: Fix range release
In reply to Greg Kroah-HartmanFrom: Dan Williams <[email protected]>
[ Upstream commit 6268d7da4d192af339f4d688942b9ccb45a65e04 ]
There are multiple locations that open-code the release of the last range in a device-dax instance. Consolidate this into a new dev_dax_trim_range() helper.
This also addresses a kmemleak report:
# cat /sys/kernel/debug/kmemleak
[..]
unreferenced object 0xffff976bd46f6240 (size 64):
comm "ndctl", pid 23556, jiffies 4299514316 (age 5406.733s)
hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 00 00 20 c3 37 00 00 00 .......... .7...
ff ff ff 7f 38 00 00 00 00 00 00 00 00 00 00 00 ....8...........
backtrace:
[<00000000064003cf>] __kmalloc_track_caller+0x136/0x379
[<00000000d85e3c52>] krealloc+0x67/0x92
[<00000000d7d3ba8a>] __alloc_dev_dax_range+0x73/0x25c
[<0000000027d58626>] devm_create_dev_dax+0x27d/0x416
[<00000000434abd43>] __dax_pmem_probe+0x1c9/0x1000 [dax_pmem_core]
[<0000000083726c1c>] dax_pmem_probe+0x10/0x1f [dax_pmem]
[<00000000b5f2319c>] nvdimm_bus_probe+0x9d/0x340 [libnvdimm]
[<00000000c055e544>] really_probe+0x230/0x48d
[<000000006cabd38e>] driver_probe_device+0x122/0x13b
[<0000000029c7b95a>] device_driver_attach+0x5b/0x60
[<0000000053e5659b>] bind_store+0xb7/0xc3
[<00000000d3bdaadc>] drv_attr_store+0x27/0x31
[<00000000949069c5>] sysfs_kf_write+0x4a/0x57
[<000000004a8b5adf>] kernfs_fop_write+0x150/0x1e5
[<00000000bded60f0>] __vfs_write+0x1b/0x34
[<00000000b92900f0>] vfs_write+0xd8/0x1d1--- drivers/dax/bus.c | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-)
drivers/dax/bus.c +21 -23
@@ -367,19 +367,28 @@ void kill_dev_dax(struct dev_dax *dev_dax) }EXPORT_SYMBOL_GPL (kill_dev_dax); -static void free_dev_dax_ranges (struct dev_dax *dev_dax) +static void trim_dev_dax_range (struct dev_dax *dev_dax) { +int i = dev_dax->nr_range -1 ; +struct range *range = &dev_dax->ranges[i].range;struct dax_region *dax_region = dev_dax->region; -int i;device_lock_assert (dax_region->dev); -for (i =0 ; i < dev_dax->nr_range; i++) { -struct range *range = &dev_dax->ranges[i].range; - -__release_region (&dax_region->res, range->start, -range_len (range)); +dev_dbg (&dev_dax->dev,"delete range[%d]: %#llx:%#llx\n" , i, + (unsigned long long )range->start, + (unsigned long long )range->end); + +__release_region (&dax_region->res, range->start,range_len (range)); +if (--dev_dax->nr_range ==0 ) { +kfree (dev_dax->ranges); + dev_dax->ranges =NULL ; } - dev_dax->nr_range =0 ; +} + +static void free_dev_dax_ranges (struct dev_dax *dev_dax) +{ +while (dev_dax->nr_range) +trim_dev_dax_range (dev_dax); }static void unregister_dev_dax (void *dev)
@@ -804,15 +813,10 @@ static int alloc_dev_dax_range(struct dev_dax *dev_dax, u64 start,return 0 ; rc =devm_register_dax_mapping (dev_dax, dev_dax->nr_range -1 ); -if (rc) { -dev_dbg (dev,"delete range[%d]: %pa:%pa\n" , dev_dax->nr_range -1 , - &alloc->start, &alloc->end); - dev_dax->nr_range--; -__release_region (res, alloc->start,resource_size (alloc)); -return rc; - } +if (rc) +trim_dev_dax_range (dev_dax); -return 0 ; +return rc; }static int adjust_dev_dax_range (struct dev_dax *dev_dax,struct resource *res,resource_size_t size)
@@ -885,12 +889,7 @@ static int dev_dax_shrink(struct dev_dax *dev_dax, resource_size_t size)if (shrink >=range_len (range)) {devm_release_action (dax_region->dev, unregister_dax_mapping, &mapping->dev); -__release_region (&dax_region->res, range->start, -range_len (range)); - dev_dax->nr_range--; -dev_dbg (dev,"delete range[%d]: %#llx:%#llx\n" , i, - (unsigned long long ) range->start, - (unsigned long long ) range->end); +trim_dev_dax_range (dev_dax); to_shrink -= shrink;if (!to_shrink)break ;
@@ -1274,7 +1273,6 @@ static void dev_dax_release(struct device *dev)put_dax (dax_dev);free_dev_dax_id (dev_dax);dax_region_put (dax_region); -kfree (dev_dax->ranges);kfree (dev_dax->pgmap);kfree (dev_dax); }
Signature · 1 line
2.27.0
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.5 release. There are 63 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, 06 Jan 2021 15:56:52 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.10.5-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.10.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v5.10:
12 builds: 12 pass, 0 fail
26 boots: 26 pass, 0 fail
64 tests: 64 pass, 0 failLinux version: 5.10.5-rc1-g18347c4f0781
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra20-ventana,
tegra210-p2371-2180, tegra210-p3450-0000,
tegra30-cardhu-a04Jon
Hello!
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.5 release. There are 63 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, 06 Jan 2021 15:56:52 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.10.5-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.10.y
and the diffstat can be found below.thanks,
greg k-h
Results from Linaro’s test farm.
No regressions detected.
Summary
------------------------------------------------------------------------
kernel: 5.10.5-rc1
git repo: ['https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git', 'https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc'] git branch: linux-5.10.y
git commit: 18347c4f07814f2fef15f3b1518b6b8a88bae75a
git describe: v5.10.4-64-g18347c4f0781
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.10.y/build/v5.10.4-64-g18347c4f0781
No regressions (compared to build v5.10.4)
No fixes (compared to build v5.10.4)
Ran 53801 total tests in the following environments and test suites.
Environments
--------------
- arc
- arm
- arm64
- dragonboard-410c
- hi6220-hikey
- i386
- juno-r2
- juno-r2-compat
- juno-r2-kasan
- mips
- parisc
- powerpc
- qemu-arm-clang
- qemu-arm64-clang
- qemu-arm64-kasan
- qemu-i386-clang
- qemu-x86_64-clang
- qemu-x86_64-kasan
- qemu-x86_64-kcsan
- qemu_arm
- qemu_arm64
- qemu_arm64-compat
- qemu_i386
- qemu_x86_64
- qemu_x86_64-compat
- riscv
- s390
- sh
- sparc
- x15
- x86
- x86-kasan
Test Suites
-----------
* build
* fwts
* igt-gpu-tools
* install-android-platform-tools-r2600
* kselftest
* kselftest-vsyscall-mode-native
* kselftest-vsyscall-mode-none
* kunit
* kvm-unit-tests
* libhugetlbfs
* linux-log-parser
* ltp-cap_bounds-tests
* ltp-commands-tests
* ltp-containers-tests
* ltp-controllers-tests
* ltp-cpuhotplug-tests
* ltp-crypto-tests
* ltp-cve-tests
* ltp-dio-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fs-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-mm-tests
* ltp-nptl-tests
* ltp-open-posix-tests
* ltp-pty-tests
* ltp-sched-tests
* ltp-securebits-tests
* ltp-syscalls-tests
* ltp-tracing-tests
* network-basic-tests
* perf
* rcutorture
* v4l2-compliance
Greetings!
Daniel Díaz
[email protected]
Signature · 2 lines
Linaro LKFT https://lkft.linaro.org
Quoted 16 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.5 release. There are 63 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, 06 Jan 2021 15:56:52 +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/v5.x/stable-review/patch-5.10.5-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-
stable-rc.git linux-5.10.y
and the diffstat can be found below.
Quoted 3 lines
thanks,
greg k-h
hello,
Compiled and booted 5.10.5-rc1+ . dmesg related shows no new errors and may be no major warning.
Having said that, "dmesg -l warn" show a BUG related stuff.
warning-5.10.5-rc1+.txt file is attached.
Signature · 2 lines
software engineer rajagiri school of engineering and technology - autonomous
[ 0.819083] Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar [ 0.819088] ... MAX_LOCKDEP_SUBCLASSES: 8 [ 0.819092] ... MAX_LOCK_DEPTH: 48 [ 0.819097] ... MAX_LOCKDEP_KEYS: 8192 [ 0.819101] ... CLASSHASH_SIZE: 4096 [ 0.819105] ... MAX_LOCKDEP_ENTRIES: 32768 [ 0.819109] ... MAX_LOCKDEP_CHAINS: 65536 [ 0.819114] ... CHAINHASH_SIZE: 32768 [ 0.819118] memory used by lock dependency info: 6365 kB [ 0.819123] memory used for stack traces: 4224 kB [ 0.819127] per task-struct memory footprint: 1920 bytes [ 0.983486] MDS CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/mds.html for more details. [ 0.985392] #3 [ 1.166946] ENERGY_PERF_BIAS: Set to 'normal', was 'performance'
[ 4.367570] =============================
[ 4.367582] [ BUG: Invalid wait context ]
[ 4.367596] 5.10.5-rc1+ #12 Not tainted
[ 4.367608] -----------------------------
[ 4.367621] ksoftirqd/3/26 is trying to lock:
[ 4.367635] ffff88810005c918 (&n->list_lock){-...}-{3:3}, at: unfreeze_partials+0x6d/0x1f0
[ 4.367671] other info that might help us debug this:
[ 4.367684] context-{2:2}
[ 4.367695] 1 lock held by ksoftirqd/3/26:
[ 4.367707] #0: ffffffffab991160 (rcu_callback){....}-{0:0}, at: rcu_core+0x340/0x8c0
[ 4.367742] stack backtrace:
[ 4.367755] CPU: 3 PID: 26 Comm: ksoftirqd/3 Not tainted 5.10.5-rc1+ #12
[ 4.367773] Hardware name: ASUSTeK COMPUTER INC. VivoBook 15_ASUS Laptop X507UAR/X507UAR, BIOS X507UAR.203 05/31/2018
[ 4.367794] Call Trace:
[ 4.367805] <IRQ>
[ 4.367820] dump_stack+0xae/0xe5
[ 4.367835] __lock_acquire.cold+0x204/0x34c
[ 4.367856] ? __lock_acquire+0x870/0x2d40
[ 4.367872] ? lockdep_hardirqs_on_prepare+0x220/0x220
[ 4.367889] ? lockdep_enabled+0x39/0x50
[ 4.367906] lock_acquire+0x236/0x510
[ 4.367922] ? unfreeze_partials+0x6d/0x1f0
[ 4.367938] ? lock_release+0x410/0x410
[ 4.367954] ? free_unref_page_commit+0x129/0x1b0
[ 4.367976] _raw_spin_lock+0x2c/0x40
[ 4.367991] ? unfreeze_partials+0x6d/0x1f0
[ 4.368006] unfreeze_partials+0x6d/0x1f0
[ 4.368023] ? nohz_balance_exit_idle+0x2c/0x250
[ 4.368043] flush_smp_call_function_queue+0xf4/0x2c0
[ 4.368059] ? slub_cpu_dead+0xf0/0xf0
[ 4.368076] __sysvec_call_function+0x71/0x250
[ 4.368093] asm_call_irq_on_stack+0x12/0x20
[ 4.368106] </IRQ>
[ 4.368119] sysvec_call_function+0x84/0xa0
[ 4.368135] asm_sysvec_call_function+0x12/0x20
[ 4.368152] RIP: 0010:__orc_find+0x6e/0xc0
[ 4.368168] Code: 37 4c 89 e8 4c 29 f8 48 89 c1 48 c1 e8 3f 48 c1 f9 02 48 01 c8 48 d1 f8 4d 8d 34 87 4c 89 f7 e8 28 ab 3b 00 49 63 06 4c 01 f0 <48> 39 c3 73 c6 4d 8d 6e fc 4d 39 fd 73 c9 4c 29 e5 48 8b 34 24 48
[ 4.368204] RSP: 0000:ffffc9000023f808 EFLAGS: 00000283
[ 4.368222] RAX: ffffffffa9c0523d RBX: ffffffffa9c05251 RCX: dffffc0000000000
[ 4.368241] RDX: 0000000000000003 RSI: ffffffffac038784 RDI: ffffffffabe63b98
[ 4.368259] RBP: ffffffffabe63b90 R08: ffffffffa9c9e4d8 R09: ffffffffac06fef1
[ 4.368277] R10: fffffbfff580dfde R11: 0000000000000001 R12: ffffffffabe63b68
[ 4.368296] R13: ffffffffabe63b9c R14: ffffffffabe63b98 R15: ffffffffabe63b94
[ 4.368333] ? ret_from_fork+0x21/0x30
[ 4.368348] ? __orc_find+0x68/0xc0
[ 4.368362] ? ret_from_fork+0xd/0x30
[ 4.368380] ? __orc_find+0x68/0xc0
[ 4.368396] unwind_next_frame+0x11d/0xa60
[ 4.368412] ? ret_from_fork+0x22/0x30
[ 4.368427] ? ret_from_fork+0x22/0x30
[ 4.368441] ? ret_from_fork+0x22/0x30
[ 4.368456] ? deref_stack_reg+0xb0/0xb0
[ 4.368473] ? __unwind_start+0x2ed/0x370
[ 4.368488] ? create_prof_cpu_mask+0x20/0x20
[ 4.368505] arch_stack_walk+0x88/0xf0
[ 4.368522] ? ret_from_fork+0x22/0x30
[ 4.368539] ? kmem_cache_free+0xff/0x400
[ 4.368553] stack_trace_save+0x91/0xc0
[ 4.368569] ? stack_trace_consume_entry+0x80/0x80
[ 4.368586] ? lock_chain_count+0x20/0x20
[ 4.368601] ? lock_chain_count+0x20/0x20
[ 4.368615] ? kmem_cache_free+0xff/0x400
[ 4.368632] kasan_save_stack+0x1b/0x40
[ 4.368646] ? kasan_save_stack+0x1b/0x40
[ 4.368661] ? kasan_set_track+0x1c/0x30
[ 4.368675] ? kasan_set_free_info+0x1b/0x30
[ 4.368690] ? __kasan_slab_free+0x110/0x150
[ 4.368706] ? slab_free_freelist_hook+0x78/0x190
[ 4.368722] ? kmem_cache_free+0xff/0x400
[ 4.368736] ? rcu_core+0x37a/0x8c0
[ 4.368750] ? __do_softirq+0x108/0x5b6
[ 4.368765] ? run_ksoftirqd+0x3a/0x60
[ 4.368780] ? smpboot_thread_fn+0x1b7/0x300
[ 4.368794] ? kthread+0x1de/0x200
[ 4.368807] ? ret_from_fork+0x22/0x30
[ 4.368823] ? __lock_acquire+0x870/0x2d40
[ 4.368840] ? __lock_acquire+0x870/0x2d40
[ 4.368861] ? lockdep_hardirqs_on_prepare+0x220/0x220
[ 4.368878] ? mark_held_locks+0x44/0x90
[ 4.368893] ? lockdep_enabled+0x39/0x50
[ 4.368910] ? mark_held_locks+0x44/0x90
[ 4.368925] kasan_set_track+0x1c/0x30
[ 4.368939] kasan_set_free_info+0x1b/0x30
[ 4.368955] __kasan_slab_free+0x110/0x150
[ 4.368972] slab_free_freelist_hook+0x78/0x190
[ 4.368988] ? rcu_core+0x37a/0x8c0
[ 4.369003] kmem_cache_free+0xff/0x400
[ 4.369021] ? rcu_core+0x340/0x8c0
[ 4.369034] rcu_core+0x37a/0x8c0
[ 4.369048] ? rcu_core+0x340/0x8c0
[ 4.369065] ? rcu_note_context_switch+0x60/0x60
[ 4.369082] ? mark_held_locks+0x24/0x90
[ 4.369097] ? lockdep_enabled+0x39/0x50
[ 4.369114] ? lock_is_held_type+0xb4/0xf0
[ 4.369131] __do_softirq+0x108/0x5b6
[ 4.369149] ? __local_bh_disable_ip+0x60/0x60
[ 4.369164] run_ksoftirqd+0x3a/0x60
[ 4.369179] smpboot_thread_fn+0x1b7/0x300
[ 4.369196] ? smpboot_register_percpu_thread+0x190/0x190
[ 4.369216] ? smpboot_register_percpu_thread+0x190/0x190
[ 4.369232] kthread+0x1de/0x200
[ 4.369246] ? kthread_create_worker_on_cpu+0xd0/0xd0
[ 4.369263] ret_from_fork+0x22/0x30
[ 12.317066] i8042: PNP: PS/2 appears to have AUX port disabled, if this is incorrect please boot with i8042.nopnp
[ 14.761446] sdhci-pci 0000:00:1e.6: failed to setup card detect gpio
[ 16.880134] i2c_hid i2c-ELAN1300:00: supply vdd not found, using dummy regulator
[ 16.881369] i2c_hid i2c-ELAN1300:00: supply vddl not found, using dummy regulator
[ 27.369213] systemd[1]: /lib/systemd/system/plymouth-start.service:16: Unit configured to use KillMode=none. This is unsafe, as it disables systemd's process lifecycle management for the service. Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'. Support for KillMode=none is deprecated and will eventually be removed.
[ 45.527373] FAT-fs (sda1): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.
[ 148.818429] show_signal_msg: 6 callbacks suppressedGreg Kroah-Hartman
maintainerQuoted 21 lines · Jeffrin Jose T
Quoted 16 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.5 release. There are 63 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, 06 Jan 2021 15:56:52 +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/v5.x/stable-review/patch-5.10.5-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-
stable-rc.git linux-5.10.y
and the diffstat can be found below.Quoted 3 lines
thanks,
greg k-h
Quoted 8 lines
hello,
Compiled and booted 5.10.5-rc1+ . dmesg related shows no new errors and may be no major warning.
Having said that, "dmesg -l warn" show a BUG related stuff.
warning-5.10.5-rc1+.txt file is attached.
Is this new? If so, can you bisect it?
thanks,
greg k-h
Quoted 32 lines · Greg Kroah-Hartman
Quoted 31 lines · Jeffrin Jose T
Quoted 19 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.5 release.
There are 63 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, 06 Jan 2021 15:56:52 +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/v5.x/stable-review/patch-5.10.5-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linu
x-
stable-rc.git linux-5.10.y
and the diffstat can be found below.Quoted 3 lines
thanks,
greg k-h
hello,
Compiled and booted 5.10.5-rc1+ . dmesg related shows no new errors and may be no major warning.
Having said that, "dmesg -l warn" show a BUG related stuff.
Quoted 7 lines
Quoted 1 line
warning-5.10.5-rc1+.txt file is attached.
Is this new? If so, can you bisect it?
thanks,
greg k-h
hello,
it seems to be new and i will try to bisect it.
Signature · 2 lines
software engineer rajagiri school of engineering and technology - autonomous
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.5 release. There are 63 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, 06 Jan 2021 15:56:52 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.10.5-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-5.10.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 5.10.5 release. There are 63 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, 06 Jan 2021 15:56:52 +0000. Anything received after that time might be too late.
Build results:
total: 154 pass: 154 fail: 0 Qemu test results: total: 427 pass: 427 fail: 0
Guenter