From: Sasha Levin Date: Wed, 30 Nov 2022 02:18:36 +0000 (-0500) Subject: Fixes for 5.4 X-Git-Tag: v5.10.157~52 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=77fce7344ab27a16d8ce875e92a209f7dee2e537;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.4 Signed-off-by: Sasha Levin --- diff --git a/queue-5.4/ceph-avoid-putting-the-realm-twice-when-decoding-sna.patch b/queue-5.4/ceph-avoid-putting-the-realm-twice-when-decoding-sna.patch new file mode 100644 index 00000000000..dc3dd1d1a42 --- /dev/null +++ b/queue-5.4/ceph-avoid-putting-the-realm-twice-when-decoding-sna.patch @@ -0,0 +1,48 @@ +From 55c10382417ab497fafc7ef36381fdbc899046d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Nov 2022 11:00:39 +0800 +Subject: ceph: avoid putting the realm twice when decoding snaps fails + +From: Xiubo Li + +[ Upstream commit 51884d153f7ec85e18d607b2467820a90e0f4359 ] + +When decoding the snaps fails it maybe leaving the 'first_realm' +and 'realm' pointing to the same snaprealm memory. And then it'll +put it twice and could cause random use-after-free, BUG_ON, etc +issues. + +Cc: stable@vger.kernel.org +Link: https://tracker.ceph.com/issues/57686 +Signed-off-by: Xiubo Li +Reviewed-by: Ilya Dryomov +Signed-off-by: Ilya Dryomov +Signed-off-by: Sasha Levin +--- + fs/ceph/snap.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c +index f2731f9efc31..97ce1bd13bad 100644 +--- a/fs/ceph/snap.c ++++ b/fs/ceph/snap.c +@@ -694,7 +694,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, + struct ceph_mds_snap_realm *ri; /* encoded */ + __le64 *snaps; /* encoded */ + __le64 *prior_parent_snaps; /* encoded */ +- struct ceph_snap_realm *realm = NULL; ++ struct ceph_snap_realm *realm; + struct ceph_snap_realm *first_realm = NULL; + struct ceph_snap_realm *realm_to_rebuild = NULL; + int rebuild_snapcs; +@@ -705,6 +705,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, + + dout("update_snap_trace deletion=%d\n", deletion); + more: ++ realm = NULL; + rebuild_snapcs = 0; + ceph_decode_need(&p, e, sizeof(*ri), bad); + ri = p; +-- +2.35.1 + diff --git a/queue-5.4/ceph-do-not-update-snapshot-context-when-there-is-no.patch b/queue-5.4/ceph-do-not-update-snapshot-context-when-there-is-no.patch new file mode 100644 index 00000000000..a8048c15b23 --- /dev/null +++ b/queue-5.4/ceph-do-not-update-snapshot-context-when-there-is-no.patch @@ -0,0 +1,129 @@ +From d691daac90063d3dbc8944da11201a85a5e3b90c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 19 Feb 2022 14:28:33 +0800 +Subject: ceph: do not update snapshot context when there is no new snapshot + +From: Xiubo Li + +[ Upstream commit 2e586641c950e7f3e7e008404bd783a466b9b590 ] + +We will only track the uppest parent snapshot realm from which we +need to rebuild the snapshot contexts _downward_ in hierarchy. For +all the others having no new snapshot we will do nothing. + +This fix will avoid calling ceph_queue_cap_snap() on some inodes +inappropriately. For example, with the code in mainline, suppose there +are 2 directory hierarchies (with 6 directories total), like this: + +/dir_X1/dir_X2/dir_X3/ +/dir_Y1/dir_Y2/dir_Y3/ + +Firstly, make a snapshot under /dir_X1/dir_X2/.snap/snap_X2, then make a +root snapshot under /.snap/root_snap. Every time we make snapshots under +/dir_Y1/..., the kclient will always try to rebuild the snap context for +snap_X2 realm and finally will always try to queue cap snaps for dir_Y2 +and dir_Y3, which makes no sense. + +That's because the snap_X2's seq is 2 and root_snap's seq is 3. So when +creating a new snapshot under /dir_Y1/... the new seq will be 4, and +the mds will send the kclient a snapshot backtrace in _downward_ +order: seqs 4, 3. + +When ceph_update_snap_trace() is called, it will always rebuild the from +the last realm, that's the root_snap. So later when rebuilding the snap +context, the current logic will always cause it to rebuild the snap_X2 +realm and then try to queue cap snaps for all the inodes related in that +realm, even though it's not necessary. + +This is accompanied by a lot of these sorts of dout messages: + + "ceph: queue_cap_snap 00000000a42b796b nothing dirty|writing" + +Fix the logic to avoid this situation. + +Also, the 'invalidate' word is not precise here. In actuality, it will +cause a rebuild of the existing snapshot contexts or just build +non-existent ones. Rename it to 'rebuild_snapcs'. + +URL: https://tracker.ceph.com/issues/44100 +Signed-off-by: Xiubo Li +Reviewed-by: Jeff Layton +Signed-off-by: Ilya Dryomov +Stable-dep-of: 51884d153f7e ("ceph: avoid putting the realm twice when decoding snaps fails") +Signed-off-by: Sasha Levin +--- + fs/ceph/snap.c | 28 +++++++++++++++++++--------- + 1 file changed, 19 insertions(+), 9 deletions(-) + +diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c +index e1b9b224fcb2..f2731f9efc31 100644 +--- a/fs/ceph/snap.c ++++ b/fs/ceph/snap.c +@@ -696,7 +696,8 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, + __le64 *prior_parent_snaps; /* encoded */ + struct ceph_snap_realm *realm = NULL; + struct ceph_snap_realm *first_realm = NULL; +- int invalidate = 0; ++ struct ceph_snap_realm *realm_to_rebuild = NULL; ++ int rebuild_snapcs; + int err = -ENOMEM; + LIST_HEAD(dirty_realms); + +@@ -704,6 +705,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, + + dout("update_snap_trace deletion=%d\n", deletion); + more: ++ rebuild_snapcs = 0; + ceph_decode_need(&p, e, sizeof(*ri), bad); + ri = p; + p += sizeof(*ri); +@@ -727,7 +729,7 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, + err = adjust_snap_realm_parent(mdsc, realm, le64_to_cpu(ri->parent)); + if (err < 0) + goto fail; +- invalidate += err; ++ rebuild_snapcs += err; + + if (le64_to_cpu(ri->seq) > realm->seq) { + dout("update_snap_trace updating %llx %p %lld -> %lld\n", +@@ -752,22 +754,30 @@ int ceph_update_snap_trace(struct ceph_mds_client *mdsc, + if (realm->seq > mdsc->last_snap_seq) + mdsc->last_snap_seq = realm->seq; + +- invalidate = 1; ++ rebuild_snapcs = 1; + } else if (!realm->cached_context) { + dout("update_snap_trace %llx %p seq %lld new\n", + realm->ino, realm, realm->seq); +- invalidate = 1; ++ rebuild_snapcs = 1; + } else { + dout("update_snap_trace %llx %p seq %lld unchanged\n", + realm->ino, realm, realm->seq); + } + +- dout("done with %llx %p, invalidated=%d, %p %p\n", realm->ino, +- realm, invalidate, p, e); ++ dout("done with %llx %p, rebuild_snapcs=%d, %p %p\n", realm->ino, ++ realm, rebuild_snapcs, p, e); + +- /* invalidate when we reach the _end_ (root) of the trace */ +- if (invalidate && p >= e) +- rebuild_snap_realms(realm, &dirty_realms); ++ /* ++ * this will always track the uppest parent realm from which ++ * we need to rebuild the snapshot contexts _downward_ in ++ * hierarchy. ++ */ ++ if (rebuild_snapcs) ++ realm_to_rebuild = realm; ++ ++ /* rebuild_snapcs when we reach the _end_ (root) of the trace */ ++ if (realm_to_rebuild && p >= e) ++ rebuild_snap_realms(realm_to_rebuild, &dirty_realms); + + if (!first_realm) + first_realm = realm; +-- +2.35.1 + diff --git a/queue-5.4/device.h-move-dev_printk-like-functions-to-dev_print.patch b/queue-5.4/device.h-move-dev_printk-like-functions-to-dev_print.patch new file mode 100644 index 00000000000..5da54811090 --- /dev/null +++ b/queue-5.4/device.h-move-dev_printk-like-functions-to-dev_print.patch @@ -0,0 +1,513 @@ +From 59146f9426b8d038777d8dcb0fd023c6d78d643d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Dec 2019 20:33:00 +0100 +Subject: device.h: move dev_printk()-like functions to dev_printk.h + +From: Greg Kroah-Hartman + +[ Upstream commit af628aae8640c268938a0c9344b4ec0d102c0a0a ] + +device.h has everything and the kitchen sink when it comes to struct +device things, so split out the printk-specific things to a separate .h +file to make things easier to maintain and manage over time. + +Cc: Suzuki K Poulose +Cc: "Rafael J. Wysocki" +Cc: Saravana Kannan +Cc: Heikki Krogerus +Link: https://lore.kernel.org/r/20191209193303.1694546-4-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: cd136706b4f9 ("USB: bcma: Make GPIO explicitly optional") +Signed-off-by: Sasha Levin +--- + include/linux/dev_printk.h | 235 +++++++++++++++++++++++++++++++++++++ + include/linux/device.h | 217 +--------------------------------- + 2 files changed, 236 insertions(+), 216 deletions(-) + create mode 100644 include/linux/dev_printk.h + +diff --git a/include/linux/dev_printk.h b/include/linux/dev_printk.h +new file mode 100644 +index 000000000000..5aad06b4ca7b +--- /dev/null ++++ b/include/linux/dev_printk.h +@@ -0,0 +1,235 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * dev_printk.h - printk messages helpers for devices ++ * ++ * Copyright (c) 2001-2003 Patrick Mochel ++ * Copyright (c) 2004-2009 Greg Kroah-Hartman ++ * Copyright (c) 2008-2009 Novell Inc. ++ * ++ */ ++ ++#ifndef _DEVICE_PRINTK_H_ ++#define _DEVICE_PRINTK_H_ ++ ++#include ++#include ++#include ++ ++#ifndef dev_fmt ++#define dev_fmt(fmt) fmt ++#endif ++ ++struct device; ++ ++#ifdef CONFIG_PRINTK ++ ++__printf(3, 0) __cold ++int dev_vprintk_emit(int level, const struct device *dev, ++ const char *fmt, va_list args); ++__printf(3, 4) __cold ++int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...); ++ ++__printf(3, 4) __cold ++void dev_printk(const char *level, const struct device *dev, ++ const char *fmt, ...); ++__printf(2, 3) __cold ++void _dev_emerg(const struct device *dev, const char *fmt, ...); ++__printf(2, 3) __cold ++void _dev_alert(const struct device *dev, const char *fmt, ...); ++__printf(2, 3) __cold ++void _dev_crit(const struct device *dev, const char *fmt, ...); ++__printf(2, 3) __cold ++void _dev_err(const struct device *dev, const char *fmt, ...); ++__printf(2, 3) __cold ++void _dev_warn(const struct device *dev, const char *fmt, ...); ++__printf(2, 3) __cold ++void _dev_notice(const struct device *dev, const char *fmt, ...); ++__printf(2, 3) __cold ++void _dev_info(const struct device *dev, const char *fmt, ...); ++ ++#else ++ ++static inline __printf(3, 0) ++int dev_vprintk_emit(int level, const struct device *dev, ++ const char *fmt, va_list args) ++{ return 0; } ++static inline __printf(3, 4) ++int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...) ++{ return 0; } ++ ++static inline void __dev_printk(const char *level, const struct device *dev, ++ struct va_format *vaf) ++{} ++static inline __printf(3, 4) ++void dev_printk(const char *level, const struct device *dev, ++ const char *fmt, ...) ++{} ++ ++static inline __printf(2, 3) ++void _dev_emerg(const struct device *dev, const char *fmt, ...) ++{} ++static inline __printf(2, 3) ++void _dev_crit(const struct device *dev, const char *fmt, ...) ++{} ++static inline __printf(2, 3) ++void _dev_alert(const struct device *dev, const char *fmt, ...) ++{} ++static inline __printf(2, 3) ++void _dev_err(const struct device *dev, const char *fmt, ...) ++{} ++static inline __printf(2, 3) ++void _dev_warn(const struct device *dev, const char *fmt, ...) ++{} ++static inline __printf(2, 3) ++void _dev_notice(const struct device *dev, const char *fmt, ...) ++{} ++static inline __printf(2, 3) ++void _dev_info(const struct device *dev, const char *fmt, ...) ++{} ++ ++#endif ++ ++/* ++ * #defines for all the dev_ macros to prefix with whatever ++ * possible use of #define dev_fmt(fmt) ... ++ */ ++ ++#define dev_emerg(dev, fmt, ...) \ ++ _dev_emerg(dev, dev_fmt(fmt), ##__VA_ARGS__) ++#define dev_crit(dev, fmt, ...) \ ++ _dev_crit(dev, dev_fmt(fmt), ##__VA_ARGS__) ++#define dev_alert(dev, fmt, ...) \ ++ _dev_alert(dev, dev_fmt(fmt), ##__VA_ARGS__) ++#define dev_err(dev, fmt, ...) \ ++ _dev_err(dev, dev_fmt(fmt), ##__VA_ARGS__) ++#define dev_warn(dev, fmt, ...) \ ++ _dev_warn(dev, dev_fmt(fmt), ##__VA_ARGS__) ++#define dev_notice(dev, fmt, ...) \ ++ _dev_notice(dev, dev_fmt(fmt), ##__VA_ARGS__) ++#define dev_info(dev, fmt, ...) \ ++ _dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__) ++ ++#if defined(CONFIG_DYNAMIC_DEBUG) ++#define dev_dbg(dev, fmt, ...) \ ++ dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__) ++#elif defined(DEBUG) ++#define dev_dbg(dev, fmt, ...) \ ++ dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__) ++#else ++#define dev_dbg(dev, fmt, ...) \ ++({ \ ++ if (0) \ ++ dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ ++}) ++#endif ++ ++#ifdef CONFIG_PRINTK ++#define dev_level_once(dev_level, dev, fmt, ...) \ ++do { \ ++ static bool __print_once __read_mostly; \ ++ \ ++ if (!__print_once) { \ ++ __print_once = true; \ ++ dev_level(dev, fmt, ##__VA_ARGS__); \ ++ } \ ++} while (0) ++#else ++#define dev_level_once(dev_level, dev, fmt, ...) \ ++do { \ ++ if (0) \ ++ dev_level(dev, fmt, ##__VA_ARGS__); \ ++} while (0) ++#endif ++ ++#define dev_emerg_once(dev, fmt, ...) \ ++ dev_level_once(dev_emerg, dev, fmt, ##__VA_ARGS__) ++#define dev_alert_once(dev, fmt, ...) \ ++ dev_level_once(dev_alert, dev, fmt, ##__VA_ARGS__) ++#define dev_crit_once(dev, fmt, ...) \ ++ dev_level_once(dev_crit, dev, fmt, ##__VA_ARGS__) ++#define dev_err_once(dev, fmt, ...) \ ++ dev_level_once(dev_err, dev, fmt, ##__VA_ARGS__) ++#define dev_warn_once(dev, fmt, ...) \ ++ dev_level_once(dev_warn, dev, fmt, ##__VA_ARGS__) ++#define dev_notice_once(dev, fmt, ...) \ ++ dev_level_once(dev_notice, dev, fmt, ##__VA_ARGS__) ++#define dev_info_once(dev, fmt, ...) \ ++ dev_level_once(dev_info, dev, fmt, ##__VA_ARGS__) ++#define dev_dbg_once(dev, fmt, ...) \ ++ dev_level_once(dev_dbg, dev, fmt, ##__VA_ARGS__) ++ ++#define dev_level_ratelimited(dev_level, dev, fmt, ...) \ ++do { \ ++ static DEFINE_RATELIMIT_STATE(_rs, \ ++ DEFAULT_RATELIMIT_INTERVAL, \ ++ DEFAULT_RATELIMIT_BURST); \ ++ if (__ratelimit(&_rs)) \ ++ dev_level(dev, fmt, ##__VA_ARGS__); \ ++} while (0) ++ ++#define dev_emerg_ratelimited(dev, fmt, ...) \ ++ dev_level_ratelimited(dev_emerg, dev, fmt, ##__VA_ARGS__) ++#define dev_alert_ratelimited(dev, fmt, ...) \ ++ dev_level_ratelimited(dev_alert, dev, fmt, ##__VA_ARGS__) ++#define dev_crit_ratelimited(dev, fmt, ...) \ ++ dev_level_ratelimited(dev_crit, dev, fmt, ##__VA_ARGS__) ++#define dev_err_ratelimited(dev, fmt, ...) \ ++ dev_level_ratelimited(dev_err, dev, fmt, ##__VA_ARGS__) ++#define dev_warn_ratelimited(dev, fmt, ...) \ ++ dev_level_ratelimited(dev_warn, dev, fmt, ##__VA_ARGS__) ++#define dev_notice_ratelimited(dev, fmt, ...) \ ++ dev_level_ratelimited(dev_notice, dev, fmt, ##__VA_ARGS__) ++#define dev_info_ratelimited(dev, fmt, ...) \ ++ dev_level_ratelimited(dev_info, dev, fmt, ##__VA_ARGS__) ++#if defined(CONFIG_DYNAMIC_DEBUG) ++/* descriptor check is first to prevent flooding with "callbacks suppressed" */ ++#define dev_dbg_ratelimited(dev, fmt, ...) \ ++do { \ ++ static DEFINE_RATELIMIT_STATE(_rs, \ ++ DEFAULT_RATELIMIT_INTERVAL, \ ++ DEFAULT_RATELIMIT_BURST); \ ++ DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ ++ if (DYNAMIC_DEBUG_BRANCH(descriptor) && \ ++ __ratelimit(&_rs)) \ ++ __dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \ ++ ##__VA_ARGS__); \ ++} while (0) ++#elif defined(DEBUG) ++#define dev_dbg_ratelimited(dev, fmt, ...) \ ++do { \ ++ static DEFINE_RATELIMIT_STATE(_rs, \ ++ DEFAULT_RATELIMIT_INTERVAL, \ ++ DEFAULT_RATELIMIT_BURST); \ ++ if (__ratelimit(&_rs)) \ ++ dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ ++} while (0) ++#else ++#define dev_dbg_ratelimited(dev, fmt, ...) \ ++do { \ ++ if (0) \ ++ dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ ++} while (0) ++#endif ++ ++#ifdef VERBOSE_DEBUG ++#define dev_vdbg dev_dbg ++#else ++#define dev_vdbg(dev, fmt, ...) \ ++({ \ ++ if (0) \ ++ dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ ++}) ++#endif ++ ++/* ++ * dev_WARN*() acts like dev_printk(), but with the key difference of ++ * using WARN/WARN_ONCE to include file/line information and a backtrace. ++ */ ++#define dev_WARN(dev, format, arg...) \ ++ WARN(1, "%s %s: " format, dev_driver_string(dev), dev_name(dev), ## arg); ++ ++#define dev_WARN_ONCE(dev, condition, format, arg...) \ ++ WARN_ONCE(condition, "%s %s: " format, \ ++ dev_driver_string(dev), dev_name(dev), ## arg) ++ ++#endif /* _DEVICE_PRINTK_H_ */ +diff --git a/include/linux/device.h b/include/linux/device.h +index 3414b5a67b46..ce8b36f34b3f 100644 +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -12,6 +12,7 @@ + #ifndef _DEVICE_H_ + #define _DEVICE_H_ + ++#include + #include + #include + #include +@@ -22,7 +23,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -1655,221 +1655,6 @@ struct device_link *device_link_add(struct device *consumer, + void device_link_del(struct device_link *link); + void device_link_remove(void *consumer, struct device *supplier); + +-#ifndef dev_fmt +-#define dev_fmt(fmt) fmt +-#endif +- +-#ifdef CONFIG_PRINTK +- +-__printf(3, 0) __cold +-int dev_vprintk_emit(int level, const struct device *dev, +- const char *fmt, va_list args); +-__printf(3, 4) __cold +-int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...); +- +-__printf(3, 4) __cold +-void dev_printk(const char *level, const struct device *dev, +- const char *fmt, ...); +-__printf(2, 3) __cold +-void _dev_emerg(const struct device *dev, const char *fmt, ...); +-__printf(2, 3) __cold +-void _dev_alert(const struct device *dev, const char *fmt, ...); +-__printf(2, 3) __cold +-void _dev_crit(const struct device *dev, const char *fmt, ...); +-__printf(2, 3) __cold +-void _dev_err(const struct device *dev, const char *fmt, ...); +-__printf(2, 3) __cold +-void _dev_warn(const struct device *dev, const char *fmt, ...); +-__printf(2, 3) __cold +-void _dev_notice(const struct device *dev, const char *fmt, ...); +-__printf(2, 3) __cold +-void _dev_info(const struct device *dev, const char *fmt, ...); +- +-#else +- +-static inline __printf(3, 0) +-int dev_vprintk_emit(int level, const struct device *dev, +- const char *fmt, va_list args) +-{ return 0; } +-static inline __printf(3, 4) +-int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...) +-{ return 0; } +- +-static inline void __dev_printk(const char *level, const struct device *dev, +- struct va_format *vaf) +-{} +-static inline __printf(3, 4) +-void dev_printk(const char *level, const struct device *dev, +- const char *fmt, ...) +-{} +- +-static inline __printf(2, 3) +-void _dev_emerg(const struct device *dev, const char *fmt, ...) +-{} +-static inline __printf(2, 3) +-void _dev_crit(const struct device *dev, const char *fmt, ...) +-{} +-static inline __printf(2, 3) +-void _dev_alert(const struct device *dev, const char *fmt, ...) +-{} +-static inline __printf(2, 3) +-void _dev_err(const struct device *dev, const char *fmt, ...) +-{} +-static inline __printf(2, 3) +-void _dev_warn(const struct device *dev, const char *fmt, ...) +-{} +-static inline __printf(2, 3) +-void _dev_notice(const struct device *dev, const char *fmt, ...) +-{} +-static inline __printf(2, 3) +-void _dev_info(const struct device *dev, const char *fmt, ...) +-{} +- +-#endif +- +-/* +- * #defines for all the dev_ macros to prefix with whatever +- * possible use of #define dev_fmt(fmt) ... +- */ +- +-#define dev_emerg(dev, fmt, ...) \ +- _dev_emerg(dev, dev_fmt(fmt), ##__VA_ARGS__) +-#define dev_crit(dev, fmt, ...) \ +- _dev_crit(dev, dev_fmt(fmt), ##__VA_ARGS__) +-#define dev_alert(dev, fmt, ...) \ +- _dev_alert(dev, dev_fmt(fmt), ##__VA_ARGS__) +-#define dev_err(dev, fmt, ...) \ +- _dev_err(dev, dev_fmt(fmt), ##__VA_ARGS__) +-#define dev_warn(dev, fmt, ...) \ +- _dev_warn(dev, dev_fmt(fmt), ##__VA_ARGS__) +-#define dev_notice(dev, fmt, ...) \ +- _dev_notice(dev, dev_fmt(fmt), ##__VA_ARGS__) +-#define dev_info(dev, fmt, ...) \ +- _dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__) +- +-#if defined(CONFIG_DYNAMIC_DEBUG) +-#define dev_dbg(dev, fmt, ...) \ +- dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__) +-#elif defined(DEBUG) +-#define dev_dbg(dev, fmt, ...) \ +- dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__) +-#else +-#define dev_dbg(dev, fmt, ...) \ +-({ \ +- if (0) \ +- dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ +-}) +-#endif +- +-#ifdef CONFIG_PRINTK +-#define dev_level_once(dev_level, dev, fmt, ...) \ +-do { \ +- static bool __print_once __read_mostly; \ +- \ +- if (!__print_once) { \ +- __print_once = true; \ +- dev_level(dev, fmt, ##__VA_ARGS__); \ +- } \ +-} while (0) +-#else +-#define dev_level_once(dev_level, dev, fmt, ...) \ +-do { \ +- if (0) \ +- dev_level(dev, fmt, ##__VA_ARGS__); \ +-} while (0) +-#endif +- +-#define dev_emerg_once(dev, fmt, ...) \ +- dev_level_once(dev_emerg, dev, fmt, ##__VA_ARGS__) +-#define dev_alert_once(dev, fmt, ...) \ +- dev_level_once(dev_alert, dev, fmt, ##__VA_ARGS__) +-#define dev_crit_once(dev, fmt, ...) \ +- dev_level_once(dev_crit, dev, fmt, ##__VA_ARGS__) +-#define dev_err_once(dev, fmt, ...) \ +- dev_level_once(dev_err, dev, fmt, ##__VA_ARGS__) +-#define dev_warn_once(dev, fmt, ...) \ +- dev_level_once(dev_warn, dev, fmt, ##__VA_ARGS__) +-#define dev_notice_once(dev, fmt, ...) \ +- dev_level_once(dev_notice, dev, fmt, ##__VA_ARGS__) +-#define dev_info_once(dev, fmt, ...) \ +- dev_level_once(dev_info, dev, fmt, ##__VA_ARGS__) +-#define dev_dbg_once(dev, fmt, ...) \ +- dev_level_once(dev_dbg, dev, fmt, ##__VA_ARGS__) +- +-#define dev_level_ratelimited(dev_level, dev, fmt, ...) \ +-do { \ +- static DEFINE_RATELIMIT_STATE(_rs, \ +- DEFAULT_RATELIMIT_INTERVAL, \ +- DEFAULT_RATELIMIT_BURST); \ +- if (__ratelimit(&_rs)) \ +- dev_level(dev, fmt, ##__VA_ARGS__); \ +-} while (0) +- +-#define dev_emerg_ratelimited(dev, fmt, ...) \ +- dev_level_ratelimited(dev_emerg, dev, fmt, ##__VA_ARGS__) +-#define dev_alert_ratelimited(dev, fmt, ...) \ +- dev_level_ratelimited(dev_alert, dev, fmt, ##__VA_ARGS__) +-#define dev_crit_ratelimited(dev, fmt, ...) \ +- dev_level_ratelimited(dev_crit, dev, fmt, ##__VA_ARGS__) +-#define dev_err_ratelimited(dev, fmt, ...) \ +- dev_level_ratelimited(dev_err, dev, fmt, ##__VA_ARGS__) +-#define dev_warn_ratelimited(dev, fmt, ...) \ +- dev_level_ratelimited(dev_warn, dev, fmt, ##__VA_ARGS__) +-#define dev_notice_ratelimited(dev, fmt, ...) \ +- dev_level_ratelimited(dev_notice, dev, fmt, ##__VA_ARGS__) +-#define dev_info_ratelimited(dev, fmt, ...) \ +- dev_level_ratelimited(dev_info, dev, fmt, ##__VA_ARGS__) +-#if defined(CONFIG_DYNAMIC_DEBUG) +-/* descriptor check is first to prevent flooding with "callbacks suppressed" */ +-#define dev_dbg_ratelimited(dev, fmt, ...) \ +-do { \ +- static DEFINE_RATELIMIT_STATE(_rs, \ +- DEFAULT_RATELIMIT_INTERVAL, \ +- DEFAULT_RATELIMIT_BURST); \ +- DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ +- if (DYNAMIC_DEBUG_BRANCH(descriptor) && \ +- __ratelimit(&_rs)) \ +- __dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \ +- ##__VA_ARGS__); \ +-} while (0) +-#elif defined(DEBUG) +-#define dev_dbg_ratelimited(dev, fmt, ...) \ +-do { \ +- static DEFINE_RATELIMIT_STATE(_rs, \ +- DEFAULT_RATELIMIT_INTERVAL, \ +- DEFAULT_RATELIMIT_BURST); \ +- if (__ratelimit(&_rs)) \ +- dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ +-} while (0) +-#else +-#define dev_dbg_ratelimited(dev, fmt, ...) \ +-do { \ +- if (0) \ +- dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ +-} while (0) +-#endif +- +-#ifdef VERBOSE_DEBUG +-#define dev_vdbg dev_dbg +-#else +-#define dev_vdbg(dev, fmt, ...) \ +-({ \ +- if (0) \ +- dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ +-}) +-#endif +- +-/* +- * dev_WARN*() acts like dev_printk(), but with the key difference of +- * using WARN/WARN_ONCE to include file/line information and a backtrace. +- */ +-#define dev_WARN(dev, format, arg...) \ +- WARN(1, "%s %s: " format, dev_driver_string(dev), dev_name(dev), ## arg); +- +-#define dev_WARN_ONCE(dev, condition, format, arg...) \ +- WARN_ONCE(condition, "%s %s: " format, \ +- dev_driver_string(dev), dev_name(dev), ## arg) +- + /* Create alias, so I can be autoloaded. */ + #define MODULE_ALIAS_CHARDEV(major,minor) \ + MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) +-- +2.35.1 + diff --git a/queue-5.4/driver-core-add-device-probe-log-helper.patch b/queue-5.4/driver-core-add-device-probe-log-helper.patch new file mode 100644 index 00000000000..d0a265dedf1 --- /dev/null +++ b/queue-5.4/driver-core-add-device-probe-log-helper.patch @@ -0,0 +1,105 @@ +From e4fa76777e32b842ca1a43cf5bbd64ecf2b7edd7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Jul 2020 16:43:21 +0200 +Subject: driver core: add device probe log helper + +From: Andrzej Hajda + +[ Upstream commit a787e5400a1ceeb0ef92d71ec43aeb35b1fa1334 ] + +During probe every time driver gets resource it should usually check for +error printk some message if it is not -EPROBE_DEFER and return the error. +This pattern is simple but requires adding few lines after any resource +acquisition code, as a result it is often omitted or implemented only +partially. +dev_err_probe helps to replace such code sequences with simple call, +so code: + if (err != -EPROBE_DEFER) + dev_err(dev, ...); + return err; +becomes: + return dev_err_probe(dev, err, ...); + +Signed-off-by: Andrzej Hajda +Reviewed-by: Rafael J. Wysocki +Reviewed-by: Mark Brown +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20200713144324.23654-2-a.hajda@samsung.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: cd136706b4f9 ("USB: bcma: Make GPIO explicitly optional") +Signed-off-by: Sasha Levin +--- + drivers/base/core.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + include/linux/device.h | 3 +++ + 2 files changed, 45 insertions(+) + +diff --git a/drivers/base/core.c b/drivers/base/core.c +index 1b016fdd1a75..20bf185d5441 100644 +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -3399,6 +3399,48 @@ define_dev_printk_level(_dev_info, KERN_INFO); + + #endif + ++/** ++ * dev_err_probe - probe error check and log helper ++ * @dev: the pointer to the struct device ++ * @err: error value to test ++ * @fmt: printf-style format string ++ * @...: arguments as specified in the format string ++ * ++ * This helper implements common pattern present in probe functions for error ++ * checking: print debug or error message depending if the error value is ++ * -EPROBE_DEFER and propagate error upwards. ++ * It replaces code sequence: ++ * if (err != -EPROBE_DEFER) ++ * dev_err(dev, ...); ++ * else ++ * dev_dbg(dev, ...); ++ * return err; ++ * with ++ * return dev_err_probe(dev, err, ...); ++ * ++ * Returns @err. ++ * ++ */ ++int dev_err_probe(const struct device *dev, int err, const char *fmt, ...) ++{ ++ struct va_format vaf; ++ va_list args; ++ ++ va_start(args, fmt); ++ vaf.fmt = fmt; ++ vaf.va = &args; ++ ++ if (err != -EPROBE_DEFER) ++ dev_err(dev, "error %d: %pV", err, &vaf); ++ else ++ dev_dbg(dev, "error %d: %pV", err, &vaf); ++ ++ va_end(args); ++ ++ return err; ++} ++EXPORT_SYMBOL_GPL(dev_err_probe); ++ + static inline bool fwnode_is_primary(struct fwnode_handle *fwnode) + { + return fwnode && !IS_ERR(fwnode->secondary); +diff --git a/include/linux/device.h b/include/linux/device.h +index ce8b36f34b3f..000514b0aaf0 100644 +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -1655,6 +1655,9 @@ struct device_link *device_link_add(struct device *consumer, + void device_link_del(struct device_link *link); + void device_link_remove(void *consumer, struct device *supplier); + ++extern __printf(3, 4) ++int dev_err_probe(const struct device *dev, int err, const char *fmt, ...); ++ + /* Create alias, so I can be autoloaded. */ + #define MODULE_ALIAS_CHARDEV(major,minor) \ + MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) +-- +2.35.1 + diff --git a/queue-5.4/firmware-coreboot-register-bus-in-module-init.patch b/queue-5.4/firmware-coreboot-register-bus-in-module-init.patch new file mode 100644 index 00000000000..c2dceef7a70 --- /dev/null +++ b/queue-5.4/firmware-coreboot-register-bus-in-module-init.patch @@ -0,0 +1,133 @@ +From 30b9127460e12a34ce30ca60b0a3db7f484875a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Oct 2022 18:10:53 -0700 +Subject: firmware: coreboot: Register bus in module init + +From: Brian Norris + +[ Upstream commit 65946690ed8d972fdb91a74ee75ac0f0f0d68321 ] + +The coreboot_table driver registers a coreboot bus while probing a +"coreboot_table" device representing the coreboot table memory region. +Probing this device (i.e., registering the bus) is a dependency for the +module_init() functions of any driver for this bus (e.g., +memconsole-coreboot.c / memconsole_driver_init()). + +With synchronous probe, this dependency works OK, as the link order in +the Makefile ensures coreboot_table_driver_init() (and thus, +coreboot_table_probe()) completes before a coreboot device driver tries +to add itself to the bus. + +With asynchronous probe, however, coreboot_table_probe() may race with +memconsole_driver_init(), and so we're liable to hit one of these two: + +1. coreboot_driver_register() eventually hits "[...] the bus was not + initialized.", and the memconsole driver fails to register; or +2. coreboot_driver_register() gets past #1, but still races with + bus_register() and hits some other undefined/crashing behavior (e.g., + in driver_find() [1]) + +We can resolve this by registering the bus in our initcall, and only +deferring "device" work (scanning the coreboot memory region and +creating sub-devices) to probe(). + +[1] Example failure, using 'driver_async_probe=*' kernel command line: + +[ 0.114217] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 +... +[ 0.114307] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 6.1.0-rc1 #63 +[ 0.114316] Hardware name: Google Scarlet (DT) +... +[ 0.114488] Call trace: +[ 0.114494] _raw_spin_lock+0x34/0x60 +[ 0.114502] kset_find_obj+0x28/0x84 +[ 0.114511] driver_find+0x30/0x50 +[ 0.114520] driver_register+0x64/0x10c +[ 0.114528] coreboot_driver_register+0x30/0x3c +[ 0.114540] memconsole_driver_init+0x24/0x30 +[ 0.114550] do_one_initcall+0x154/0x2e0 +[ 0.114560] do_initcall_level+0x134/0x160 +[ 0.114571] do_initcalls+0x60/0xa0 +[ 0.114579] do_basic_setup+0x28/0x34 +[ 0.114588] kernel_init_freeable+0xf8/0x150 +[ 0.114596] kernel_init+0x2c/0x12c +[ 0.114607] ret_from_fork+0x10/0x20 +[ 0.114624] Code: 5280002b 1100054a b900092a f9800011 (885ffc01) +[ 0.114631] ---[ end trace 0000000000000000 ]--- + +Fixes: b81e3140e412 ("firmware: coreboot: Make bus registration symmetric") +Cc: +Signed-off-by: Brian Norris +Reviewed-by: Guenter Roeck +Reviewed-by: Stephen Boyd +Link: https://lore.kernel.org/r/20221019180934.1.If29e167d8a4771b0bf4a39c89c6946ed764817b9@changeid +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/firmware/google/coreboot_table.c | 37 +++++++++++++++++++----- + 1 file changed, 29 insertions(+), 8 deletions(-) + +diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c +index 0205987a4fd4..568074148f62 100644 +--- a/drivers/firmware/google/coreboot_table.c ++++ b/drivers/firmware/google/coreboot_table.c +@@ -152,12 +152,8 @@ static int coreboot_table_probe(struct platform_device *pdev) + if (!ptr) + return -ENOMEM; + +- ret = bus_register(&coreboot_bus_type); +- if (!ret) { +- ret = coreboot_table_populate(dev, ptr); +- if (ret) +- bus_unregister(&coreboot_bus_type); +- } ++ ret = coreboot_table_populate(dev, ptr); ++ + memunmap(ptr); + + return ret; +@@ -172,7 +168,6 @@ static int __cb_dev_unregister(struct device *dev, void *dummy) + static int coreboot_table_remove(struct platform_device *pdev) + { + bus_for_each_dev(&coreboot_bus_type, NULL, NULL, __cb_dev_unregister); +- bus_unregister(&coreboot_bus_type); + return 0; + } + +@@ -202,6 +197,32 @@ static struct platform_driver coreboot_table_driver = { + .of_match_table = of_match_ptr(coreboot_of_match), + }, + }; +-module_platform_driver(coreboot_table_driver); ++ ++static int __init coreboot_table_driver_init(void) ++{ ++ int ret; ++ ++ ret = bus_register(&coreboot_bus_type); ++ if (ret) ++ return ret; ++ ++ ret = platform_driver_register(&coreboot_table_driver); ++ if (ret) { ++ bus_unregister(&coreboot_bus_type); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void __exit coreboot_table_driver_exit(void) ++{ ++ platform_driver_unregister(&coreboot_table_driver); ++ bus_unregister(&coreboot_bus_type); ++} ++ ++module_init(coreboot_table_driver_init); ++module_exit(coreboot_table_driver_exit); ++ + MODULE_AUTHOR("Google, Inc."); + MODULE_LICENSE("GPL"); +-- +2.35.1 + diff --git a/queue-5.4/firmware-google-release-devices-before-unregistering.patch b/queue-5.4/firmware-google-release-devices-before-unregistering.patch new file mode 100644 index 00000000000..aba34e11514 --- /dev/null +++ b/queue-5.4/firmware-google-release-devices-before-unregistering.patch @@ -0,0 +1,45 @@ +From 2f01cdf0f0f61b1e7f0bf606a2800df6fa890b85 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Nov 2019 11:19:29 +0100 +Subject: firmware: google: Release devices before unregistering the bus + +From: Patrick Rudolph + +[ Upstream commit cae0970ee9c4527f189aac378c50e2f0ed020418 ] + +Fix a bug where the kernel module can't be loaded after it has been +unloaded as the devices are still present and conflicting with the +to be created coreboot devices. + +Signed-off-by: Patrick Rudolph +Link: https://lore.kernel.org/r/20191118101934.22526-2-patrick.rudolph@9elements.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 65946690ed8d ("firmware: coreboot: Register bus in module init") +Signed-off-by: Sasha Levin +--- + drivers/firmware/google/coreboot_table.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c +index 8d132e4f008a..0205987a4fd4 100644 +--- a/drivers/firmware/google/coreboot_table.c ++++ b/drivers/firmware/google/coreboot_table.c +@@ -163,8 +163,15 @@ static int coreboot_table_probe(struct platform_device *pdev) + return ret; + } + ++static int __cb_dev_unregister(struct device *dev, void *dummy) ++{ ++ device_unregister(dev); ++ return 0; ++} ++ + static int coreboot_table_remove(struct platform_device *pdev) + { ++ bus_for_each_dev(&coreboot_bus_type, NULL, NULL, __cb_dev_unregister); + bus_unregister(&coreboot_bus_type); + return 0; + } +-- +2.35.1 + diff --git a/queue-5.4/iio-ms5611-simplify-io-callback-parameters.patch b/queue-5.4/iio-ms5611-simplify-io-callback-parameters.patch new file mode 100644 index 00000000000..3703c326ca7 --- /dev/null +++ b/queue-5.4/iio-ms5611-simplify-io-callback-parameters.patch @@ -0,0 +1,188 @@ +From ed7b9f25ead4bf22cbd69d366facd3e039102946 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Oct 2021 16:21:10 +0200 +Subject: iio: ms5611: Simplify IO callback parameters + +From: Lars-Peter Clausen + +[ Upstream commit dc19fa63ad80a636fdbc1a02153d1ab140cb901f ] + +The ms5611 passes &indio_dev->dev as a parameter to all its IO callbacks +only to directly cast the struct device back to struct iio_dev. And the +struct iio_dev is then only used to get the drivers state struct. + +Simplify this a bit by passing the state struct directly. This makes it a +bit easier to follow what the code is doing. + +Signed-off-by: Lars-Peter Clausen +Link: https://lore.kernel.org/r/20211020142110.7060-1-lars@metafoo.de +Signed-off-by: Jonathan Cameron +Stable-dep-of: 17f442e7e475 ("iio: pressure: ms5611: fixed value compensation bug") +Signed-off-by: Sasha Levin +--- + drivers/iio/pressure/ms5611.h | 6 +++--- + drivers/iio/pressure/ms5611_core.c | 7 +++---- + drivers/iio/pressure/ms5611_i2c.c | 11 ++++------- + drivers/iio/pressure/ms5611_spi.c | 17 +++++++---------- + 4 files changed, 17 insertions(+), 24 deletions(-) + +diff --git a/drivers/iio/pressure/ms5611.h b/drivers/iio/pressure/ms5611.h +index bc06271fa38b..345f3902e3e3 100644 +--- a/drivers/iio/pressure/ms5611.h ++++ b/drivers/iio/pressure/ms5611.h +@@ -50,9 +50,9 @@ struct ms5611_state { + const struct ms5611_osr *pressure_osr; + const struct ms5611_osr *temp_osr; + +- int (*reset)(struct device *dev); +- int (*read_prom_word)(struct device *dev, int index, u16 *word); +- int (*read_adc_temp_and_pressure)(struct device *dev, ++ int (*reset)(struct ms5611_state *st); ++ int (*read_prom_word)(struct ms5611_state *st, int index, u16 *word); ++ int (*read_adc_temp_and_pressure)(struct ms5611_state *st, + s32 *temp, s32 *pressure); + + struct ms5611_chip_info *chip_info; +diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c +index f5db9fa086f3..29dd648a308c 100644 +--- a/drivers/iio/pressure/ms5611_core.c ++++ b/drivers/iio/pressure/ms5611_core.c +@@ -85,8 +85,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev) + struct ms5611_state *st = iio_priv(indio_dev); + + for (i = 0; i < MS5611_PROM_WORDS_NB; i++) { +- ret = st->read_prom_word(&indio_dev->dev, +- i, &st->chip_info->prom[i]); ++ ret = st->read_prom_word(st, i, &st->chip_info->prom[i]); + if (ret < 0) { + dev_err(&indio_dev->dev, + "failed to read prom at %d\n", i); +@@ -108,7 +107,7 @@ static int ms5611_read_temp_and_pressure(struct iio_dev *indio_dev, + int ret; + struct ms5611_state *st = iio_priv(indio_dev); + +- ret = st->read_adc_temp_and_pressure(&indio_dev->dev, temp, pressure); ++ ret = st->read_adc_temp_and_pressure(st, temp, pressure); + if (ret < 0) { + dev_err(&indio_dev->dev, + "failed to read temperature and pressure\n"); +@@ -196,7 +195,7 @@ static int ms5611_reset(struct iio_dev *indio_dev) + int ret; + struct ms5611_state *st = iio_priv(indio_dev); + +- ret = st->reset(&indio_dev->dev); ++ ret = st->reset(st); + if (ret < 0) { + dev_err(&indio_dev->dev, "failed to reset device\n"); + return ret; +diff --git a/drivers/iio/pressure/ms5611_i2c.c b/drivers/iio/pressure/ms5611_i2c.c +index 8089c59adce5..3175816e657f 100644 +--- a/drivers/iio/pressure/ms5611_i2c.c ++++ b/drivers/iio/pressure/ms5611_i2c.c +@@ -18,17 +18,15 @@ + + #include "ms5611.h" + +-static int ms5611_i2c_reset(struct device *dev) ++static int ms5611_i2c_reset(struct ms5611_state *st) + { +- struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); +- + return i2c_smbus_write_byte(st->client, MS5611_RESET); + } + +-static int ms5611_i2c_read_prom_word(struct device *dev, int index, u16 *word) ++static int ms5611_i2c_read_prom_word(struct ms5611_state *st, int index, ++ u16 *word) + { + int ret; +- struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); + + ret = i2c_smbus_read_word_swapped(st->client, + MS5611_READ_PROM_WORD + (index << 1)); +@@ -55,11 +53,10 @@ static int ms5611_i2c_read_adc(struct ms5611_state *st, s32 *val) + return 0; + } + +-static int ms5611_i2c_read_adc_temp_and_pressure(struct device *dev, ++static int ms5611_i2c_read_adc_temp_and_pressure(struct ms5611_state *st, + s32 *temp, s32 *pressure) + { + int ret; +- struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); + const struct ms5611_osr *osr = st->temp_osr; + + ret = i2c_smbus_write_byte(st->client, osr->cmd); +diff --git a/drivers/iio/pressure/ms5611_spi.c b/drivers/iio/pressure/ms5611_spi.c +index c3854594cd26..6e9cab61bc32 100644 +--- a/drivers/iio/pressure/ms5611_spi.c ++++ b/drivers/iio/pressure/ms5611_spi.c +@@ -13,18 +13,17 @@ + + #include "ms5611.h" + +-static int ms5611_spi_reset(struct device *dev) ++static int ms5611_spi_reset(struct ms5611_state *st) + { + u8 cmd = MS5611_RESET; +- struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); + + return spi_write_then_read(st->client, &cmd, 1, NULL, 0); + } + +-static int ms5611_spi_read_prom_word(struct device *dev, int index, u16 *word) ++static int ms5611_spi_read_prom_word(struct ms5611_state *st, int index, ++ u16 *word) + { + int ret; +- struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); + + ret = spi_w8r16be(st->client, MS5611_READ_PROM_WORD + (index << 1)); + if (ret < 0) +@@ -35,11 +34,10 @@ static int ms5611_spi_read_prom_word(struct device *dev, int index, u16 *word) + return 0; + } + +-static int ms5611_spi_read_adc(struct device *dev, s32 *val) ++static int ms5611_spi_read_adc(struct ms5611_state *st, s32 *val) + { + int ret; + u8 buf[3] = { MS5611_READ_ADC }; +- struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); + + ret = spi_write_then_read(st->client, buf, 1, buf, 3); + if (ret < 0) +@@ -50,11 +48,10 @@ static int ms5611_spi_read_adc(struct device *dev, s32 *val) + return 0; + } + +-static int ms5611_spi_read_adc_temp_and_pressure(struct device *dev, ++static int ms5611_spi_read_adc_temp_and_pressure(struct ms5611_state *st, + s32 *temp, s32 *pressure) + { + int ret; +- struct ms5611_state *st = iio_priv(dev_to_iio_dev(dev)); + const struct ms5611_osr *osr = st->temp_osr; + + /* +@@ -66,7 +63,7 @@ static int ms5611_spi_read_adc_temp_and_pressure(struct device *dev, + return ret; + + usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL)); +- ret = ms5611_spi_read_adc(dev, temp); ++ ret = ms5611_spi_read_adc(st, temp); + if (ret < 0) + return ret; + +@@ -76,7 +73,7 @@ static int ms5611_spi_read_adc_temp_and_pressure(struct device *dev, + return ret; + + usleep_range(osr->conv_usec, osr->conv_usec + (osr->conv_usec / 10UL)); +- return ms5611_spi_read_adc(dev, pressure); ++ return ms5611_spi_read_adc(st, pressure); + } + + static int ms5611_spi_probe(struct spi_device *spi) +-- +2.35.1 + diff --git a/queue-5.4/iio-pressure-ms5611-fixed-value-compensation-bug.patch b/queue-5.4/iio-pressure-ms5611-fixed-value-compensation-bug.patch new file mode 100644 index 00000000000..b45d4fc3611 --- /dev/null +++ b/queue-5.4/iio-pressure-ms5611-fixed-value-compensation-bug.patch @@ -0,0 +1,173 @@ +From e5edf2aa006a6a4f220d8feda44d567740be7bd4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Oct 2022 15:58:20 +0200 +Subject: iio: pressure: ms5611: fixed value compensation bug + +From: Mitja Spes + +[ Upstream commit 17f442e7e47579d3881fc4d47354eaef09302e6f ] + +When using multiple instances of this driver the compensation PROM was +overwritten by the last initialized sensor. Now each sensor has own PROM +storage. + +Signed-off-by: Mitja Spes +Fixes: 9690d81a02dc ("iio: pressure: ms5611: add support for MS5607 temperature and pressure sensor") +Link: https://lore.kernel.org/r/20221021135827.1444793-2-mitja@lxnav.com +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/pressure/ms5611.h | 12 +++---- + drivers/iio/pressure/ms5611_core.c | 51 ++++++++++++++++-------------- + 2 files changed, 31 insertions(+), 32 deletions(-) + +diff --git a/drivers/iio/pressure/ms5611.h b/drivers/iio/pressure/ms5611.h +index 345f3902e3e3..5e2d2d4d87b5 100644 +--- a/drivers/iio/pressure/ms5611.h ++++ b/drivers/iio/pressure/ms5611.h +@@ -25,13 +25,6 @@ enum { + MS5607, + }; + +-struct ms5611_chip_info { +- u16 prom[MS5611_PROM_WORDS_NB]; +- +- int (*temp_and_pressure_compensate)(struct ms5611_chip_info *chip_info, +- s32 *temp, s32 *pressure); +-}; +- + /* + * OverSampling Rate descriptor. + * Warning: cmd MUST be kept aligned on a word boundary (see +@@ -50,12 +43,15 @@ struct ms5611_state { + const struct ms5611_osr *pressure_osr; + const struct ms5611_osr *temp_osr; + ++ u16 prom[MS5611_PROM_WORDS_NB]; ++ + int (*reset)(struct ms5611_state *st); + int (*read_prom_word)(struct ms5611_state *st, int index, u16 *word); + int (*read_adc_temp_and_pressure)(struct ms5611_state *st, + s32 *temp, s32 *pressure); + +- struct ms5611_chip_info *chip_info; ++ int (*compensate_temp_and_pressure)(struct ms5611_state *st, s32 *temp, ++ s32 *pressure); + struct regulator *vdd; + }; + +diff --git a/drivers/iio/pressure/ms5611_core.c b/drivers/iio/pressure/ms5611_core.c +index 29dd648a308c..511ebdeafbe4 100644 +--- a/drivers/iio/pressure/ms5611_core.c ++++ b/drivers/iio/pressure/ms5611_core.c +@@ -85,7 +85,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev) + struct ms5611_state *st = iio_priv(indio_dev); + + for (i = 0; i < MS5611_PROM_WORDS_NB; i++) { +- ret = st->read_prom_word(st, i, &st->chip_info->prom[i]); ++ ret = st->read_prom_word(st, i, &st->prom[i]); + if (ret < 0) { + dev_err(&indio_dev->dev, + "failed to read prom at %d\n", i); +@@ -93,7 +93,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev) + } + } + +- if (!ms5611_prom_is_valid(st->chip_info->prom, MS5611_PROM_WORDS_NB)) { ++ if (!ms5611_prom_is_valid(st->prom, MS5611_PROM_WORDS_NB)) { + dev_err(&indio_dev->dev, "PROM integrity check failed\n"); + return -ENODEV; + } +@@ -114,21 +114,20 @@ static int ms5611_read_temp_and_pressure(struct iio_dev *indio_dev, + return ret; + } + +- return st->chip_info->temp_and_pressure_compensate(st->chip_info, +- temp, pressure); ++ return st->compensate_temp_and_pressure(st, temp, pressure); + } + +-static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info, ++static int ms5611_temp_and_pressure_compensate(struct ms5611_state *st, + s32 *temp, s32 *pressure) + { + s32 t = *temp, p = *pressure; + s64 off, sens, dt; + +- dt = t - (chip_info->prom[5] << 8); +- off = ((s64)chip_info->prom[2] << 16) + ((chip_info->prom[4] * dt) >> 7); +- sens = ((s64)chip_info->prom[1] << 15) + ((chip_info->prom[3] * dt) >> 8); ++ dt = t - (st->prom[5] << 8); ++ off = ((s64)st->prom[2] << 16) + ((st->prom[4] * dt) >> 7); ++ sens = ((s64)st->prom[1] << 15) + ((st->prom[3] * dt) >> 8); + +- t = 2000 + ((chip_info->prom[6] * dt) >> 23); ++ t = 2000 + ((st->prom[6] * dt) >> 23); + if (t < 2000) { + s64 off2, sens2, t2; + +@@ -154,17 +153,17 @@ static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_inf + return 0; + } + +-static int ms5607_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info, ++static int ms5607_temp_and_pressure_compensate(struct ms5611_state *st, + s32 *temp, s32 *pressure) + { + s32 t = *temp, p = *pressure; + s64 off, sens, dt; + +- dt = t - (chip_info->prom[5] << 8); +- off = ((s64)chip_info->prom[2] << 17) + ((chip_info->prom[4] * dt) >> 6); +- sens = ((s64)chip_info->prom[1] << 16) + ((chip_info->prom[3] * dt) >> 7); ++ dt = t - (st->prom[5] << 8); ++ off = ((s64)st->prom[2] << 17) + ((st->prom[4] * dt) >> 6); ++ sens = ((s64)st->prom[1] << 16) + ((st->prom[3] * dt) >> 7); + +- t = 2000 + ((chip_info->prom[6] * dt) >> 23); ++ t = 2000 + ((st->prom[6] * dt) >> 23); + if (t < 2000) { + s64 off2, sens2, t2, tmp; + +@@ -342,15 +341,6 @@ static int ms5611_write_raw(struct iio_dev *indio_dev, + + static const unsigned long ms5611_scan_masks[] = {0x3, 0}; + +-static struct ms5611_chip_info chip_info_tbl[] = { +- [MS5611] = { +- .temp_and_pressure_compensate = ms5611_temp_and_pressure_compensate, +- }, +- [MS5607] = { +- .temp_and_pressure_compensate = ms5607_temp_and_pressure_compensate, +- } +-}; +- + static const struct iio_chan_spec ms5611_channels[] = { + { + .type = IIO_PRESSURE, +@@ -433,7 +423,20 @@ int ms5611_probe(struct iio_dev *indio_dev, struct device *dev, + struct ms5611_state *st = iio_priv(indio_dev); + + mutex_init(&st->lock); +- st->chip_info = &chip_info_tbl[type]; ++ ++ switch (type) { ++ case MS5611: ++ st->compensate_temp_and_pressure = ++ ms5611_temp_and_pressure_compensate; ++ break; ++ case MS5607: ++ st->compensate_temp_and_pressure = ++ ms5607_temp_and_pressure_compensate; ++ break; ++ default: ++ return -EINVAL; ++ } ++ + st->temp_osr = + &ms5611_avail_temp_osr[ARRAY_SIZE(ms5611_avail_temp_osr) - 1]; + st->pressure_osr = +-- +2.35.1 + diff --git a/queue-5.4/jbd2-drop-pointless-wakeup-from-jbd2_journal_stop.patch b/queue-5.4/jbd2-drop-pointless-wakeup-from-jbd2_journal_stop.patch new file mode 100644 index 00000000000..22a77ebede3 --- /dev/null +++ b/queue-5.4/jbd2-drop-pointless-wakeup-from-jbd2_journal_stop.patch @@ -0,0 +1,50 @@ +From a4129775c6479663ad5f5cbbdc61517bfe03530c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2019 17:44:22 +0100 +Subject: jbd2: Drop pointless wakeup from jbd2_journal_stop() + +From: Jan Kara + +[ Upstream commit 5559b2d81b51de75cb7864bb1fbb82982f7e8fff ] + +When we drop last handle from a transaction and journal->j_barrier_count +> 0, jbd2_journal_stop() wakes up journal->j_wait_transaction_locked +wait queue. This looks pointless - wait for outstanding handles always +happens on journal->j_wait_updates waitqueue. +journal->j_wait_transaction_locked is used to wait for transaction state +changes and by start_this_handle() for waiting until +journal->j_barrier_count drops to 0. The first case is clearly +irrelevant here since only jbd2 thread changes transaction state. The +second case looks related but jbd2_journal_unlock_updates() is +responsible for the wakeup in this case. So just drop the wakeup. + +Reviewed-by: Theodore Ts'o +Signed-off-by: Jan Kara +Link: https://lore.kernel.org/r/20191105164437.32602-16-jack@suse.cz +Signed-off-by: Theodore Ts'o +Stable-dep-of: f6b1a1cf1c3e ("ext4: fix use-after-free in ext4_ext_shift_extents") +Signed-off-by: Sasha Levin +--- + fs/jbd2/transaction.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c +index ce66dbbf0f90..6d78648392f0 100644 +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -1850,11 +1850,8 @@ int jbd2_journal_stop(handle_t *handle) + * once we do this, we must not dereference transaction + * pointer again. + */ +- if (atomic_dec_and_test(&transaction->t_updates)) { ++ if (atomic_dec_and_test(&transaction->t_updates)) + wake_up(&journal->j_wait_updates); +- if (journal->j_barrier_count) +- wake_up(&journal->j_wait_transaction_locked); +- } + + rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_); + +-- +2.35.1 + diff --git a/queue-5.4/jbd2-factor-out-common-parts-of-stopping-and-restart.patch b/queue-5.4/jbd2-factor-out-common-parts-of-stopping-and-restart.patch new file mode 100644 index 00000000000..375fa03f610 --- /dev/null +++ b/queue-5.4/jbd2-factor-out-common-parts-of-stopping-and-restart.patch @@ -0,0 +1,205 @@ +From 598c77a12e153e9e93ccd16bd289141f0eea4a9e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2019 17:44:23 +0100 +Subject: jbd2: Factor out common parts of stopping and restarting a handle + +From: Jan Kara + +[ Upstream commit ec8b6f600e49dc87a8564807fec4193bf93ee2b5 ] + +jbd2__journal_restart() has quite some code that is common with +jbd2_journal_stop(). Factor this functionality into stop_this_handle() +helper and use it from both functions. Note that this also drops +t_handle_lock protection from jbd2__journal_restart() as +jbd2_journal_stop() does the same thing without it. + +Signed-off-by: Jan Kara +Link: https://lore.kernel.org/r/20191105164437.32602-17-jack@suse.cz +Signed-off-by: Theodore Ts'o +Stable-dep-of: f6b1a1cf1c3e ("ext4: fix use-after-free in ext4_ext_shift_extents") +Signed-off-by: Sasha Levin +--- + fs/jbd2/transaction.c | 98 ++++++++++++++++++++----------------------- + 1 file changed, 46 insertions(+), 52 deletions(-) + +diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c +index 6d78648392f0..ee9a778c8fbe 100644 +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -514,12 +514,17 @@ handle_t *jbd2_journal_start(journal_t *journal, int nblocks) + } + EXPORT_SYMBOL(jbd2_journal_start); + +-void jbd2_journal_free_reserved(handle_t *handle) ++static void __jbd2_journal_unreserve_handle(handle_t *handle) + { + journal_t *journal = handle->h_journal; + + WARN_ON(!handle->h_reserved); + sub_reserved_credits(journal, handle->h_buffer_credits); ++} ++ ++void jbd2_journal_free_reserved(handle_t *handle) ++{ ++ __jbd2_journal_unreserve_handle(handle); + jbd2_free_handle(handle); + } + EXPORT_SYMBOL(jbd2_journal_free_reserved); +@@ -657,6 +662,28 @@ int jbd2_journal_extend(handle_t *handle, int nblocks) + return result; + } + ++static void stop_this_handle(handle_t *handle) ++{ ++ transaction_t *transaction = handle->h_transaction; ++ journal_t *journal = transaction->t_journal; ++ ++ J_ASSERT(journal_current_handle() == handle); ++ J_ASSERT(atomic_read(&transaction->t_updates) > 0); ++ current->journal_info = NULL; ++ atomic_sub(handle->h_buffer_credits, ++ &transaction->t_outstanding_credits); ++ if (handle->h_rsv_handle) ++ __jbd2_journal_unreserve_handle(handle->h_rsv_handle); ++ if (atomic_dec_and_test(&transaction->t_updates)) ++ wake_up(&journal->j_wait_updates); ++ ++ rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_); ++ /* ++ * Scope of the GFP_NOFS context is over here and so we can restore the ++ * original alloc context. ++ */ ++ memalloc_nofs_restore(handle->saved_alloc_context); ++} + + /** + * int jbd2_journal_restart() - restart a handle . +@@ -679,52 +706,34 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, gfp_t gfp_mask) + transaction_t *transaction = handle->h_transaction; + journal_t *journal; + tid_t tid; +- int need_to_start, ret; ++ int need_to_start; + + /* If we've had an abort of any type, don't even think about + * actually doing the restart! */ + if (is_handle_aborted(handle)) + return 0; + journal = transaction->t_journal; ++ tid = transaction->t_tid; + + /* + * First unlink the handle from its current transaction, and start the + * commit on that. + */ +- J_ASSERT(atomic_read(&transaction->t_updates) > 0); +- J_ASSERT(journal_current_handle() == handle); +- +- read_lock(&journal->j_state_lock); +- spin_lock(&transaction->t_handle_lock); +- atomic_sub(handle->h_buffer_credits, +- &transaction->t_outstanding_credits); +- if (handle->h_rsv_handle) { +- sub_reserved_credits(journal, +- handle->h_rsv_handle->h_buffer_credits); +- } +- if (atomic_dec_and_test(&transaction->t_updates)) +- wake_up(&journal->j_wait_updates); +- tid = transaction->t_tid; +- spin_unlock(&transaction->t_handle_lock); ++ jbd_debug(2, "restarting handle %p\n", handle); ++ stop_this_handle(handle); + handle->h_transaction = NULL; +- current->journal_info = NULL; + +- jbd_debug(2, "restarting handle %p\n", handle); ++ /* ++ * TODO: If we use READ_ONCE / WRITE_ONCE for j_commit_request we can ++ * get rid of pointless j_state_lock traffic like this. ++ */ ++ read_lock(&journal->j_state_lock); + need_to_start = !tid_geq(journal->j_commit_request, tid); + read_unlock(&journal->j_state_lock); + if (need_to_start) + jbd2_log_start_commit(journal, tid); +- +- rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_); + handle->h_buffer_credits = nblocks; +- /* +- * Restore the original nofs context because the journal restart +- * is basically the same thing as journal stop and start. +- * start_this_handle will start a new nofs context. +- */ +- memalloc_nofs_restore(handle->saved_alloc_context); +- ret = start_this_handle(journal, handle, gfp_mask); +- return ret; ++ return start_this_handle(journal, handle, gfp_mask); + } + EXPORT_SYMBOL(jbd2__journal_restart); + +@@ -1734,16 +1743,12 @@ int jbd2_journal_stop(handle_t *handle) + * Handle is already detached from the transaction so there is + * nothing to do other than free the handle. + */ +- if (handle->h_rsv_handle) +- jbd2_free_handle(handle->h_rsv_handle); ++ memalloc_nofs_restore(handle->saved_alloc_context); + goto free_and_exit; + } + journal = transaction->t_journal; + tid = transaction->t_tid; + +- J_ASSERT(journal_current_handle() == handle); +- J_ASSERT(atomic_read(&transaction->t_updates) > 0); +- + if (is_handle_aborted(handle)) + err = -EIO; + +@@ -1813,9 +1818,6 @@ int jbd2_journal_stop(handle_t *handle) + + if (handle->h_sync) + transaction->t_synchronous_commit = 1; +- current->journal_info = NULL; +- atomic_sub(handle->h_buffer_credits, +- &transaction->t_outstanding_credits); + + /* + * If the handle is marked SYNC, we need to set another commit +@@ -1845,27 +1847,19 @@ int jbd2_journal_stop(handle_t *handle) + } + + /* +- * Once we drop t_updates, if it goes to zero the transaction +- * could start committing on us and eventually disappear. So +- * once we do this, we must not dereference transaction +- * pointer again. ++ * Once stop_this_handle() drops t_updates, the transaction could start ++ * committing on us and eventually disappear. So we must not ++ * dereference transaction pointer again after calling ++ * stop_this_handle(). + */ +- if (atomic_dec_and_test(&transaction->t_updates)) +- wake_up(&journal->j_wait_updates); +- +- rwsem_release(&journal->j_trans_commit_map, 1, _THIS_IP_); ++ stop_this_handle(handle); + + if (wait_for_commit) + err = jbd2_log_wait_commit(journal, tid); + +- if (handle->h_rsv_handle) +- jbd2_journal_free_reserved(handle->h_rsv_handle); + free_and_exit: +- /* +- * Scope of the GFP_NOFS context is over here and so we can restore the +- * original alloc context. +- */ +- memalloc_nofs_restore(handle->saved_alloc_context); ++ if (handle->h_rsv_handle) ++ jbd2_free_handle(handle->h_rsv_handle); + jbd2_free_handle(handle); + return err; + } +-- +2.35.1 + diff --git a/queue-5.4/jbd2-reorganize-jbd2_journal_stop.patch b/queue-5.4/jbd2-reorganize-jbd2_journal_stop.patch new file mode 100644 index 00000000000..1f00af20d48 --- /dev/null +++ b/queue-5.4/jbd2-reorganize-jbd2_journal_stop.patch @@ -0,0 +1,104 @@ +From 526e6da0a66d8df0bb8243398f73b1ebf9279a78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2019 17:44:20 +0100 +Subject: jbd2: Reorganize jbd2_journal_stop() + +From: Jan Kara + +[ Upstream commit dfaf5ffda227be3e867fee7c0f6a66749392fbd0 ] + +Move code in jbd2_journal_stop() around a bit. It removes some +unnecessary code duplication and will make factoring out parts common +with jbd2__journal_restart() easier. + +Reviewed-by: Theodore Ts'o +Signed-off-by: Jan Kara +Link: https://lore.kernel.org/r/20191105164437.32602-14-jack@suse.cz +Signed-off-by: Theodore Ts'o +Stable-dep-of: f6b1a1cf1c3e ("ext4: fix use-after-free in ext4_ext_shift_extents") +Signed-off-by: Sasha Levin +--- + fs/jbd2/transaction.c | 40 ++++++++++++++++------------------------ + 1 file changed, 16 insertions(+), 24 deletions(-) + +diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c +index 09f4d00fece2..ce66dbbf0f90 100644 +--- a/fs/jbd2/transaction.c ++++ b/fs/jbd2/transaction.c +@@ -1722,41 +1722,34 @@ int jbd2_journal_stop(handle_t *handle) + tid_t tid; + pid_t pid; + ++ if (--handle->h_ref > 0) { ++ jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1, ++ handle->h_ref); ++ if (is_handle_aborted(handle)) ++ return -EIO; ++ return 0; ++ } + if (!transaction) { + /* +- * Handle is already detached from the transaction so +- * there is nothing to do other than decrease a refcount, +- * or free the handle if refcount drops to zero ++ * Handle is already detached from the transaction so there is ++ * nothing to do other than free the handle. + */ +- if (--handle->h_ref > 0) { +- jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1, +- handle->h_ref); +- return err; +- } else { +- if (handle->h_rsv_handle) +- jbd2_free_handle(handle->h_rsv_handle); +- goto free_and_exit; +- } ++ if (handle->h_rsv_handle) ++ jbd2_free_handle(handle->h_rsv_handle); ++ goto free_and_exit; + } + journal = transaction->t_journal; ++ tid = transaction->t_tid; + + J_ASSERT(journal_current_handle() == handle); ++ J_ASSERT(atomic_read(&transaction->t_updates) > 0); + + if (is_handle_aborted(handle)) + err = -EIO; +- else +- J_ASSERT(atomic_read(&transaction->t_updates) > 0); +- +- if (--handle->h_ref > 0) { +- jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1, +- handle->h_ref); +- return err; +- } + + jbd_debug(4, "Handle %p going down\n", handle); + trace_jbd2_handle_stats(journal->j_fs_dev->bd_dev, +- transaction->t_tid, +- handle->h_type, handle->h_line_no, ++ tid, handle->h_type, handle->h_line_no, + jiffies - handle->h_start_jiffies, + handle->h_sync, handle->h_requested_credits, + (handle->h_requested_credits - +@@ -1841,7 +1834,7 @@ int jbd2_journal_stop(handle_t *handle) + jbd_debug(2, "transaction too old, requesting commit for " + "handle %p\n", handle); + /* This is non-blocking */ +- jbd2_log_start_commit(journal, transaction->t_tid); ++ jbd2_log_start_commit(journal, tid); + + /* + * Special case: JBD2_SYNC synchronous updates require us +@@ -1857,7 +1850,6 @@ int jbd2_journal_stop(handle_t *handle) + * once we do this, we must not dereference transaction + * pointer again. + */ +- tid = transaction->t_tid; + if (atomic_dec_and_test(&transaction->t_updates)) { + wake_up(&journal->j_wait_updates); + if (journal->j_barrier_count) +-- +2.35.1 + diff --git a/queue-5.4/revert-usb-bcma-add-a-check-for-devm_gpiod_get.patch b/queue-5.4/revert-usb-bcma-add-a-check-for-devm_gpiod_get.patch new file mode 100644 index 00000000000..3f05a418d92 --- /dev/null +++ b/queue-5.4/revert-usb-bcma-add-a-check-for-devm_gpiod_get.patch @@ -0,0 +1,57 @@ +From c0ac030adcb47352b739d19e20d28b2fa3290a56 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 31 Aug 2021 08:54:19 +0200 +Subject: Revert "USB: bcma: Add a check for devm_gpiod_get" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rafał Miłecki + +[ Upstream commit d91adc5322ab53df4b6d1989242bfb6c63163eb2 ] + +This reverts commit f3de5d857bb2362b00e2a8d4bc886cd49dcb66db. + +That commit broke USB on all routers that have USB always powered on and +don't require toggling any GPIO. It's a majority of devices actually. + +The original code worked and seemed safe: vcc GPIO is optional and +bcma_hci_platform_power_gpio() takes care of checking the pointer before +using it. + +This revert fixes: +[ 10.801127] bcma_hcd: probe of bcma0:11 failed with error -2 + +Fixes: f3de5d857bb2 ("USB: bcma: Add a check for devm_gpiod_get") +Cc: stable +Cc: Chuhong Yuan +Signed-off-by: Rafał Miłecki +Link: https://lore.kernel.org/r/20210831065419.18371-1-zajec5@gmail.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: cd136706b4f9 ("USB: bcma: Make GPIO explicitly optional") +Signed-off-by: Sasha Levin +--- + drivers/usb/host/bcma-hcd.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c +index 652fa29beb27..2400a826397a 100644 +--- a/drivers/usb/host/bcma-hcd.c ++++ b/drivers/usb/host/bcma-hcd.c +@@ -406,12 +406,9 @@ static int bcma_hcd_probe(struct bcma_device *core) + return -ENOMEM; + usb_dev->core = core; + +- if (core->dev.of_node) { ++ if (core->dev.of_node) + usb_dev->gpio_desc = devm_gpiod_get(&core->dev, "vcc", + GPIOD_OUT_HIGH); +- if (IS_ERR(usb_dev->gpio_desc)) +- return PTR_ERR(usb_dev->gpio_desc); +- } + + switch (core->id.id) { + case BCMA_CORE_USB20_HOST: +-- +2.35.1 + diff --git a/queue-5.4/series b/queue-5.4/series index abd835e83c6..847a70ca117 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -49,3 +49,17 @@ iio-light-apds9960-fix-wrong-register-for-gesture-gain.patch iio-core-fix-entry-not-deleted-when-iio_register_sw_trigger_type-fails.patch init-kconfig-fix-cc_has_asm_goto_tied_output-test-wi.patch nios2-add-force-for-vmlinuz.gz.patch +iio-ms5611-simplify-io-callback-parameters.patch +iio-pressure-ms5611-fixed-value-compensation-bug.patch +ceph-do-not-update-snapshot-context-when-there-is-no.patch +ceph-avoid-putting-the-realm-twice-when-decoding-sna.patch +usb-bcma-add-a-check-for-devm_gpiod_get.patch +device.h-move-dev_printk-like-functions-to-dev_print.patch +driver-core-add-device-probe-log-helper.patch +revert-usb-bcma-add-a-check-for-devm_gpiod_get.patch +usb-bcma-make-gpio-explicitly-optional.patch +firmware-google-release-devices-before-unregistering.patch +firmware-coreboot-register-bus-in-module-init.patch +jbd2-reorganize-jbd2_journal_stop.patch +jbd2-drop-pointless-wakeup-from-jbd2_journal_stop.patch +jbd2-factor-out-common-parts-of-stopping-and-restart.patch diff --git a/queue-5.4/usb-bcma-add-a-check-for-devm_gpiod_get.patch b/queue-5.4/usb-bcma-add-a-check-for-devm_gpiod_get.patch new file mode 100644 index 00000000000..1701c3ae7de --- /dev/null +++ b/queue-5.4/usb-bcma-add-a-check-for-devm_gpiod_get.patch @@ -0,0 +1,43 @@ +From b9ea1129368b877a7143b714b7e09b6820a28000 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Oct 2019 16:35:32 +0800 +Subject: USB: bcma: Add a check for devm_gpiod_get + +From: Chuhong Yuan + +[ Upstream commit f3de5d857bb2362b00e2a8d4bc886cd49dcb66db ] + +bcma_hcd_probe misses a check for devm_gpiod_get and may miss +the error. +Add a check for it and return the error if a failure occurs. + +Signed-off-by: Chuhong Yuan +Link: https://lore.kernel.org/r/20191016083531.5734-1-hslester96@gmail.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: cd136706b4f9 ("USB: bcma: Make GPIO explicitly optional") +Signed-off-by: Sasha Levin +--- + drivers/usb/host/bcma-hcd.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c +index 2400a826397a..652fa29beb27 100644 +--- a/drivers/usb/host/bcma-hcd.c ++++ b/drivers/usb/host/bcma-hcd.c +@@ -406,9 +406,12 @@ static int bcma_hcd_probe(struct bcma_device *core) + return -ENOMEM; + usb_dev->core = core; + +- if (core->dev.of_node) ++ if (core->dev.of_node) { + usb_dev->gpio_desc = devm_gpiod_get(&core->dev, "vcc", + GPIOD_OUT_HIGH); ++ if (IS_ERR(usb_dev->gpio_desc)) ++ return PTR_ERR(usb_dev->gpio_desc); ++ } + + switch (core->id.id) { + case BCMA_CORE_USB20_HOST: +-- +2.35.1 + diff --git a/queue-5.4/usb-bcma-make-gpio-explicitly-optional.patch b/queue-5.4/usb-bcma-make-gpio-explicitly-optional.patch new file mode 100644 index 00000000000..413af996fdd --- /dev/null +++ b/queue-5.4/usb-bcma-make-gpio-explicitly-optional.patch @@ -0,0 +1,71 @@ +From fc6503b10494eb9d7c522ee466f06a34e9868e76 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Nov 2022 10:07:53 +0100 +Subject: USB: bcma: Make GPIO explicitly optional +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Linus Walleij + +[ Upstream commit cd136706b4f925aa5d316642543babac90d45910 ] + +What the code does is to not check the return value from +devm_gpiod_get() and then avoid using an erroneous GPIO descriptor +with IS_ERR_OR_NULL(). + +This will miss real errors from the GPIO core that should not be +ignored, such as probe deferral. + +Instead request the GPIO as explicitly optional, which means that +if it doesn't exist, the descriptor returned will be NULL. + +Then we can add error handling and also avoid just doing this on +the device tree path, and simplify the site where the optional +GPIO descriptor is used. + +There were some problems with cleaning up this GPIO descriptor +use in the past, but this is the proper way to deal with it. + +Cc: Rafał Miłecki +Cc: Chuhong Yuan +Signed-off-by: Linus Walleij +Cc: stable +Link: https://lore.kernel.org/r/20221107090753.1404679-1-linus.walleij@linaro.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/host/bcma-hcd.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c +index 2400a826397a..d8f2af8fb89d 100644 +--- a/drivers/usb/host/bcma-hcd.c ++++ b/drivers/usb/host/bcma-hcd.c +@@ -285,7 +285,7 @@ static void bcma_hci_platform_power_gpio(struct bcma_device *dev, bool val) + { + struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev); + +- if (IS_ERR_OR_NULL(usb_dev->gpio_desc)) ++ if (!usb_dev->gpio_desc) + return; + + gpiod_set_value(usb_dev->gpio_desc, val); +@@ -406,9 +406,11 @@ static int bcma_hcd_probe(struct bcma_device *core) + return -ENOMEM; + usb_dev->core = core; + +- if (core->dev.of_node) +- usb_dev->gpio_desc = devm_gpiod_get(&core->dev, "vcc", +- GPIOD_OUT_HIGH); ++ usb_dev->gpio_desc = devm_gpiod_get_optional(&core->dev, "vcc", ++ GPIOD_OUT_HIGH); ++ if (IS_ERR(usb_dev->gpio_desc)) ++ return dev_err_probe(&core->dev, PTR_ERR(usb_dev->gpio_desc), ++ "error obtaining VCC GPIO"); + + switch (core->id.id) { + case BCMA_CORE_USB20_HOST: +-- +2.35.1 +