Re: [PATCH v2 01/10] devm-helpers: introduce devm_mutex_init
Hello Andy Thanks for the review. On 12/4/23 21:11, Andy Shevchenko wrote: On Mon, Dec 4, 2023 at 8:07 PM George Stark wrote: Using of devm API leads to certain order of releasing resources. So all dependent resources which are not devm-wrapped should be deleted with respect to devm-release order. Mutex is one of such objects that often is bound to other resources and has no own devm wrapping. Since mutex_destroy() actually does nothing in non-debug builds frequently calling mutex_destroy() is just ignored which is safe for now but wrong formally and can lead to a problem if mutex_destroy() is extended so introduce devm_mutex_init(). ... Do you need to include mutex.h? It's already included in linux/device.h which is included in devm-helpers. Should I include mutex.h explicitly? ... +/** + * devm_mutex_init - Resource-managed mutex initialization + * @dev: Device which lifetime work is bound to + * @lock: Pointer to a mutex + * + * Initialize mutex which is automatically destroyed when driver is detached. the driver Have you run scripts/kernel-doc -v -Wall -none ... against this file? I'm pretty sure it will complain. It does with warning "No description found for return value". Fixed + */ -- Best regards George
[PATCH 12/27] tty: hvc: convert to u8 and size_t
Switch character types to u8 and sizes to size_t. To conform to characters/sizes in the rest of the tty layer. Signed-off-by: Jiri Slaby (SUSE) Cc: Michael Ellerman Cc: Nicholas Piggin Cc: Christophe Leroy Cc: Amit Shah Cc: Arnd Bergmann Cc: Paul Walmsley Cc: Palmer Dabbelt Cc: Albert Ou Cc: linuxppc-dev@lists.ozlabs.org Cc: virtualizat...@lists.linux.dev Cc: linux-ri...@lists.infradead.org --- arch/powerpc/include/asm/hvconsole.h | 4 ++-- arch/powerpc/include/asm/hvsi.h| 18 arch/powerpc/include/asm/opal.h| 8 +--- arch/powerpc/platforms/powernv/opal.c | 14 +++-- arch/powerpc/platforms/pseries/hvconsole.c | 4 ++-- drivers/char/virtio_console.c | 10 - drivers/tty/hvc/hvc_console.h | 4 ++-- drivers/tty/hvc/hvc_dcc.c | 24 +++--- drivers/tty/hvc/hvc_iucv.c | 18 drivers/tty/hvc/hvc_opal.c | 5 +++-- drivers/tty/hvc/hvc_riscv_sbi.c| 9 drivers/tty/hvc/hvc_rtas.c | 11 +- drivers/tty/hvc/hvc_udbg.c | 9 drivers/tty/hvc/hvc_vio.c | 18 drivers/tty/hvc/hvc_xen.c | 23 +++-- drivers/tty/hvc/hvsi_lib.c | 20 ++ 16 files changed, 107 insertions(+), 92 deletions(-) diff --git a/arch/powerpc/include/asm/hvconsole.h b/arch/powerpc/include/asm/hvconsole.h index ccb2034506f0..d841a97010a0 100644 --- a/arch/powerpc/include/asm/hvconsole.h +++ b/arch/powerpc/include/asm/hvconsole.h @@ -21,8 +21,8 @@ * Vio firmware always attempts to fetch MAX_VIO_GET_CHARS chars. The 'count' * parm is included to conform to put_chars() function pointer template */ -extern int hvc_get_chars(uint32_t vtermno, char *buf, int count); -extern int hvc_put_chars(uint32_t vtermno, const char *buf, int count); +extern ssize_t hvc_get_chars(uint32_t vtermno, u8 *buf, size_t count); +extern ssize_t hvc_put_chars(uint32_t vtermno, const u8 *buf, size_t count); /* Provided by HVC VIO */ void hvc_vio_init_early(void); diff --git a/arch/powerpc/include/asm/hvsi.h b/arch/powerpc/include/asm/hvsi.h index 464a7519ed64..9058edcb632b 100644 --- a/arch/powerpc/include/asm/hvsi.h +++ b/arch/powerpc/include/asm/hvsi.h @@ -64,7 +64,7 @@ struct hvsi_priv { unsigned intinbuf_len; /* data in input buffer */ unsigned char inbuf[HVSI_INBUF_SIZE]; unsigned intinbuf_cur; /* Cursor in input buffer */ - unsigned intinbuf_pktlen; /* packet length from cursor */ + size_t inbuf_pktlen; /* packet length from cursor */ atomic_tseqno; /* packet sequence number */ unsigned intopened:1; /* driver opened */ unsigned intestablished:1; /* protocol established */ @@ -72,24 +72,26 @@ struct hvsi_priv { unsigned intmctrl_update:1; /* modem control updated */ unsigned short mctrl; /* modem control */ struct tty_struct *tty; /* tty structure */ - int (*get_chars)(uint32_t termno, char *buf, int count); - int (*put_chars)(uint32_t termno, const char *buf, int count); + ssize_t (*get_chars)(uint32_t termno, u8 *buf, size_t count); + ssize_t (*put_chars)(uint32_t termno, const u8 *buf, size_t count); uint32_ttermno; }; /* hvsi lib functions */ struct hvc_struct; extern void hvsilib_init(struct hvsi_priv *pv, -int (*get_chars)(uint32_t termno, char *buf, int count), -int (*put_chars)(uint32_t termno, const char *buf, - int count), +ssize_t (*get_chars)(uint32_t termno, u8 *buf, + size_t count), +ssize_t (*put_chars)(uint32_t termno, const u8 *buf, + size_t count), int termno, int is_console); extern int hvsilib_open(struct hvsi_priv *pv, struct hvc_struct *hp); extern void hvsilib_close(struct hvsi_priv *pv, struct hvc_struct *hp); extern int hvsilib_read_mctrl(struct hvsi_priv *pv); extern int hvsilib_write_mctrl(struct hvsi_priv *pv, int dtr); extern void hvsilib_establish(struct hvsi_priv *pv); -extern int hvsilib_get_chars(struct hvsi_priv *pv, char *buf, int count); -extern int hvsilib_put_chars(struct hvsi_priv *pv, const char *buf, int count); +extern ssize_t hvsilib_get_chars(struct hvsi_priv *pv, u8 *buf, size_t count); +extern ssize_t hvsilib_put_chars(struct hvsi_priv *pv, const u8 *buf, +size_t count); #endif /* _HVSI_H */ diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index b66b0c615f4f..af304e6cb486 100644 --- a/arch/powerpc/include/asm/opal.h +++
[PATCH 10/27] tty: ehv_bytechan: convert to u8 and size_t
Switch character types to u8 and sizes to size_t. To conform to characters/sizes in the rest of the tty layer. Signed-off-by: Jiri Slaby (SUSE) Cc: Laurentiu Tudor Cc: linuxppc-dev@lists.ozlabs.org --- drivers/tty/ehv_bytechan.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index cc9f4338da60..69508d7a4135 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -49,7 +49,7 @@ struct ehv_bc_data { unsigned int tx_irq; spinlock_t lock;/* lock for transmit buffer */ - unsigned char buf[BUF_SIZE];/* transmit circular buffer */ + u8 buf[BUF_SIZE]; /* transmit circular buffer */ unsigned int head; /* circular buffer head */ unsigned int tail; /* circular buffer tail */ @@ -138,9 +138,9 @@ static int find_console_handle(void) static unsigned int local_ev_byte_channel_send(unsigned int handle, unsigned int *count, - const char *p) + const u8 *p) { - char buffer[EV_BYTE_CHANNEL_MAX_BYTES]; + u8 buffer[EV_BYTE_CHANNEL_MAX_BYTES]; unsigned int c = *count; /* @@ -166,7 +166,7 @@ static unsigned int local_ev_byte_channel_send(unsigned int handle, * has been sent, or if some error has occurred. * */ -static void byte_channel_spin_send(const char data) +static void byte_channel_spin_send(const u8 data) { int ret, count; @@ -474,8 +474,7 @@ static ssize_t ehv_bc_tty_write(struct tty_struct *ttys, const u8 *s, { struct ehv_bc_data *bc = ttys->driver_data; unsigned long flags; - unsigned int len; - unsigned int written = 0; + size_t len, written = 0; while (1) { spin_lock_irqsave(>lock, flags); -- 2.43.0
Re: [PATCH v2 00/35] bitops: add atomic find_bit() operations
On Mon, Dec 04, 2023 at 07:51:01PM +0100, Jan Kara wrote: > Hello Yury! > > On Sun 03-12-23 11:23:47, Yury Norov wrote: > > Add helpers around test_and_{set,clear}_bit() that allow to search for > > clear or set bits and flip them atomically. > > > > The target patterns may look like this: > > > > for (idx = 0; idx < nbits; idx++) > > if (test_and_clear_bit(idx, bitmap)) > > do_something(idx); > > > > Or like this: > > > > do { > > bit = find_first_bit(bitmap, nbits); > > if (bit >= nbits) > > return nbits; > > } while (!test_and_clear_bit(bit, bitmap)); > > return bit; > > > > In both cases, the opencoded loop may be converted to a single function > > or iterator call. Correspondingly: > > > > for_each_test_and_clear_bit(idx, bitmap, nbits) > > do_something(idx); > > > > Or: > > return find_and_clear_bit(bitmap, nbits); > > These are fine cleanups but they actually don't address the case that has > triggered all these changes - namely the xarray use of find_next_bit() in > xas_find_chunk(). > > ... > > This series is a result of discussion [1]. All find_bit() functions imply > > exclusive access to the bitmaps. However, KCSAN reports quite a number > > of warnings related to find_bit() API. Some of them are not pointing > > to real bugs because in many situations people intentionally allow > > concurrent bitmap operations. > > > > If so, find_bit() can be annotated such that KCSAN will ignore it: > > > > bit = data_race(find_first_bit(bitmap, nbits)); > > No, this is not a correct thing to do. If concurrent bitmap changes can > happen, find_first_bit() as it is currently implemented isn't ever a safe > choice because it can call __ffs(0) which is dangerous as you properly note > above. I proposed adding READ_ONCE() into find_first_bit() / find_next_bit() > implementation to fix this issue but you disliked that. So other option we > have is adding find_first_bit() and find_next_bit() variants that take > volatile 'addr' and we have to use these in code like xas_find_chunk() > which cannot be converted to your new helpers. Here is some examples when concurrent operations with plain find_bit() are acceptable: - two threads running find_*_bit(): safe wrt ffs(0) and returns correct value, because underlying bitmap is unchanged; - find_next_bit() in parallel with set or clear_bit(), when modifying a bit prior to the start bit to search: safe and correct; - find_first_bit() in parallel with set_bit(): safe, but may return wrong bit number; - find_first_zero_bit() in parallel with clear_bit(): same as above. In last 2 cases find_bit() may not return a correct bit number, but it may be OK if caller requires any (not exactly first) set or clear bit, correspondingly. In such cases, KCSAN may be safely silenced. > > This series addresses the other important case where people really need > > atomic find ops. As the following patches show, the resulting code > > looks safer and more verbose comparing to opencoded loops followed by > > atomic bit flips. > > > > In [1] Mirsad reported 2% slowdown in a single-thread search test when > > switching find_bit() function to treat bitmaps as volatile arrays. On > > the other hand, kernel robot in the same thread reported +3.7% to the > > performance of will-it-scale.per_thread_ops test. > > It was actually me who reported the regression here [2] but whatever :) > > [2] https://lore.kernel.org/all/20231011150252.32737-1-j...@suse.cz My apologize. > > Assuming that our compilers are sane and generate better code against > > properly annotated data, the above discrepancy doesn't look weird. When > > running on non-volatile bitmaps, plain find_bit() outperforms atomic > > find_and_bit(), and vice-versa. > > > > So, all users of find_bit() API, where heavy concurrency is expected, > > are encouraged to switch to atomic find_and_bit() as appropriate. > > Well, all users where any concurrency can happen should switch. Otherwise > they are prone to the (admittedly mostly theoretical) data race issue. > > Honza > -- > Jan Kara > SUSE Labs, CR
Re: [PATCH V4] tools/perf: Add perf binary dependent rule for shellcheck log in Makefile.perf
> On 06-Dec-2023, at 3:20 AM, Arnaldo Carvalho de Melo wrote: > > Em Mon, Nov 27, 2023 at 11:12:57AM +, James Clark escreveu: >> On 23/11/2023 16:02, Athira Rajeev wrote: >>> --- a/tools/perf/Makefile.perf >>> @@ -1134,6 +1152,7 @@ bpf-skel-clean: >>> $(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS) >>> >>> clean:: $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean >>> $(LIBSYMBOL)-clean $(LIBPERF)-clean fixdep-clean python-clean >>> bpf-skel-clean tests-coresight-targets-clean >>> + $(Q)$(MAKE) -f $(srctree)/tools/perf/tests/Makefile.tests clean >>> $(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive >>> $(OUTPUT)perf-iostat $(LANG_BINDINGS) >>> $(Q)find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete >>> -o -name '\.*.d' -delete >>> $(Q)$(RM) $(OUTPUT).config-detected > > While merging perf-tools-next with torvalds/master I noticed that maybe > we better have the above added line as: > > + $(call QUIET_CLEAN, tests) $(Q)$(MAKE) -f > $(srctree)/tools/perf/tests/Makefile.tests clean > > No? > > Anyway I'm merging as-is, but it just hit my eye while merging, > > - Arnaldo Hi Arnaldo As Ian pointed we removed Makefile.tests as part of : https://lore.kernel.org/lkml/20231129213428.2227448-1-irog...@google.com/ Thanks Athira
[linux-next:master] BUILD REGRESSION 0f5f12ac05f36f117e793656c3f560625e927f1b
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master branch HEAD: 0f5f12ac05f36f117e793656c3f560625e927f1b Add linux-next specific files for 20231205 Error/Warning reports: https://lore.kernel.org/oe-kbuild-all/202312051416.yirwcymp-...@intel.com https://lore.kernel.org/oe-kbuild-all/202312051418.jkbrbdyp-...@intel.com https://lore.kernel.org/oe-kbuild-all/202312051419.dsbnpgym-...@intel.com https://lore.kernel.org/oe-kbuild-all/202312051913.e5iif8qz-...@intel.com https://lore.kernel.org/oe-kbuild-all/202312051935.ixiyu8kn-...@intel.com https://lore.kernel.org/oe-kbuild-all/202312052245.yfpbsgnh-...@intel.com https://lore.kernel.org/oe-kbuild-all/202312060025.bdeqzrwx-...@intel.com https://lore.kernel.org/oe-kbuild-all/202312060311.tnsv2fl2-...@intel.com https://lore.kernel.org/oe-kbuild-all/202312060355.m0ejtq4x-...@intel.com https://lore.kernel.org/oe-kbuild-all/202312061137.qgjj4ntc-...@intel.com Error/Warning: (recently discovered and may have been fixed) aarch64-linux-ld: qcom_stats.c:(.text+0x470): undefined reference to `qmp_send' arch/mips/kernel/crash.c:96:6: warning: no previous prototype for 'default_machine_crash_shutdown' [-Wmissing-prototypes] arch/mips/kernel/machine_kexec.c:161:6: warning: no previous prototype for 'kexec_nonboot_cpu_jump' [-Wmissing-prototypes] arch/mips/kernel/machine_kexec.c:170:6: warning: conflicting types for 'kexec_reboot'; have 'void(void)' arch/mips/kernel/machine_kexec.c:170:6: warning: no previous prototype for 'kexec_reboot' [-Wmissing-prototypes] arch/mips/kernel/machine_kexec.c:77:17: error: 'kexec_args' undeclared (first use in this function) drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_process.c:1671:9: sparse:struct dma_fence * drivers/gpu/drm/amd/amdgpu/../amdkfd/kfd_process.c:1671:9: sparse:struct dma_fence [noderef] __rcu * drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c:2765:36: sparse:struct dma_fence * drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c:2765:36: sparse:struct dma_fence [noderef] __rcu * drivers/leds/leds-sun50i-a100.c:309:12: error: call to __compiletime_assert_280 declared with 'error' attribute: FIELD_PREP: value too large for the field drivers/media/i2c/saa6752hs.c:598:18: error: implicit declaration of function 'v4l2_subdev_state_get_format' [-Werror=implicit-function-declaration] qcom_stats.c:(.text+0x33c): undefined reference to `qmp_send' qcom_stats.c:(.text+0x398): undefined reference to `__aeabi_uldivmod' qcom_stats.c:(.text+0x6c4): undefined reference to `__udivdi3' qcom_stats.c:(.text+0x8a0): undefined reference to `qmp_get' qcom_stats.c:(.text.qcom_ddr_stats_show+0x14c): undefined reference to `__udivdi3' Unverified Error/Warning (likely false positive, please contact us if interested): drivers/gpu/drm/i915/display/intel_fbdev_fb.c:111 intel_fbdev_fb_fill_info() error: uninitialized symbol 'vaddr'. Error/Warning ids grouped by kconfigs: gcc_recent_errors |-- alpha-randconfig-r013-20211213 | |-- (.init.text):undefined-reference-to-__auxiliary_driver_register | |-- (.text):undefined-reference-to-auxiliary_device_init | |-- alpha-linux-ld:(.init.text):undefined-reference-to-__auxiliary_driver_register | |-- alpha-linux-ld:(.text):undefined-reference-to-__auxiliary_device_add | `-- alpha-linux-ld:(.text):undefined-reference-to-auxiliary_device_init |-- arc-randconfig-c031-20221114 | `-- drivers-media-i2c-saa6752hs.c:error:implicit-declaration-of-function-v4l2_subdev_state_get_format |-- arm-allyesconfig | `-- qcom_stats.c:(.text):undefined-reference-to-__aeabi_uldivmod |-- arm64-randconfig-r034-20230701 | |-- aarch64-linux-ld:qcom_stats.c:(.text):undefined-reference-to-qmp_send | |-- qcom_stats.c:(.text):undefined-reference-to-qmp_get | `-- qcom_stats.c:(.text):undefined-reference-to-qmp_send |-- i386-randconfig-061-20231205 | `-- lib-zstd-compress-zstd_fast.c:sparse:sparse:Using-plain-integer-as-NULL-pointer |-- i386-randconfig-063-20231205 | `-- lib-zstd-compress-zstd_fast.c:sparse:sparse:Using-plain-integer-as-NULL-pointer |-- i386-randconfig-141-20231205 | |-- block-bdev.c-bdev_open_by_dev()-warn:possible-memory-leak-of-handle | |-- drivers-gpu-drm-amd-amdgpu-amdgpu_connectors.c-amdgpu_connector_dvi_detect()-warn:inconsistent-indenting | |-- drivers-gpu-drm-amd-amdgpu-amdgpu_ras.c-amdgpu_ras_query_error_status_helper()-error:we-previously-assumed-info-could-be-null-(see-line-) | |-- drivers-gpu-drm-drm_gpuvm.c-drm_gpuvm_exec_lock_range()-error:uninitialized-symbol-ret-. | |-- drivers-hwtracing-stm-core.c-stm_register_device()-error:double-free-of-stm | |-- fs-bcachefs-btree_update_interior.c-bch2_btree_update_start()-warn:inconsistent-returns-c-gc_lock-. | |-- fs-bcachefs-btree_write_buffer.c-bch2_btree_write_buffer_flush_locked()-error:we-previously-assumed-iter.path-could-be-null-(see-line-) | |-- fs-bcachefs-recovery.c-bch2_journal_replay()-error:uninitialized-symbol-ret-. | |-- lib-zstd-common
Re: [PATCH net-next v2 0/9] net*: Convert to platform remove callback returning void
Hello: This series was applied to netdev/net-next.git (main) by Jakub Kicinski : On Mon, 4 Dec 2023 19:30:40 +0100 you wrote: > Hello, > > (implicit) v1 of this series can be found at > https://lore.kernel.org/netdev/20231117095922.876489-1-u.kleine-koe...@pengutronix.de. > Changes since then: > > - Dropped patch #1 as Alex objected. Patch #1 (was #2 before) now >converts ipa to remove_new() and introduces an error message in the >error path that failed before. > > [...] Here is the summary with links: - [net-next,v2,1/9] net: ipa: Convert to platform remove callback returning void https://git.kernel.org/netdev/net-next/c/a92dbb9cdf04 - [net-next,v2,2/9] net: fjes: Convert to platform remove callback returning void https://git.kernel.org/netdev/net-next/c/2ce19934a4dc - [net-next,v2,3/9] net: pcs: rzn1-miic: Convert to platform remove callback returning void https://git.kernel.org/netdev/net-next/c/e36dc85c245f - [net-next,v2,4/9] net: sfp: Convert to platform remove callback returning void https://git.kernel.org/netdev/net-next/c/bb1afee98466 - [net-next,v2,5/9] net: wan/fsl_ucc_hdlc: Convert to platform remove callback returning void https://git.kernel.org/netdev/net-next/c/2d0c06fd39be - [net-next,v2,6/9] net: wan/ixp4xx_hss: Convert to platform remove callback returning void https://git.kernel.org/netdev/net-next/c/2d8590858753 - [net-next,v2,7/9] net: wwan: qcom_bam_dmux: Convert to platform remove callback returning void https://git.kernel.org/netdev/net-next/c/a06041e2f4ae - [net-next,v2,8/9] ieee802154: fakelb: Convert to platform remove callback returning void (no matching commit) - [net-next,v2,9/9] ieee802154: hwsim: Convert to platform remove callback returning void (no matching commit) You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html
[powerpc:fixes-test] BUILD SUCCESS 4b3338aaa74d7d4ec5b6734dc298f0db94ec83d2
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git fixes-test branch HEAD: 4b3338aaa74d7d4ec5b6734dc298f0db94ec83d2 powerpc/ftrace: Fix stack teardown in ftrace_no_trace Warning ids grouped by kconfigs: clang_recent_errors `-- powerpc-randconfig-002-20231206 `-- fs-bcachefs-checksum.c:warning:stack-frame-size-()-exceeds-limit-()-in-__bch2_encrypt_bio elapsed time: 1003m configs tested: 122 configs skipped: 150 The following configs have been built successfully. More configs may be tested in the coming days. tested configs: alpha allnoconfig gcc alpha defconfig gcc arc allnoconfig gcc arc defconfig gcc arc randconfig-001-20231206 gcc arc randconfig-002-20231206 gcc arm allnoconfig gcc arm64allmodconfig clang arm64 allnoconfig gcc arm64 defconfig gcc csky allnoconfig gcc cskydefconfig gcc csky randconfig-001-20231206 gcc csky randconfig-002-20231206 gcc hexagon allmodconfig clang hexagon allyesconfig clang i386 allmodconfig clang i386 allnoconfig clang i386 allyesconfig clang i386 randconfig-011-20231206 gcc i386 randconfig-012-20231206 gcc i386 randconfig-013-20231206 gcc i386 randconfig-014-20231206 gcc i386 randconfig-015-20231206 gcc i386 randconfig-016-20231206 gcc loongarchallmodconfig gcc loongarch allnoconfig gcc loongarchallyesconfig gcc loongarch defconfig gcc loongarch randconfig-001-20231206 gcc loongarch randconfig-002-20231206 gcc m68k allmodconfig gcc m68k allnoconfig gcc m68k allyesconfig gcc m68kdefconfig gcc microblaze allmodconfig gcc microblazeallnoconfig gcc microblaze allyesconfig gcc microblaze defconfig gcc mips allmodconfig gcc mips allyesconfig gcc nios2allmodconfig gcc nios2 allnoconfig gcc nios2allyesconfig gcc nios2 defconfig gcc nios2 randconfig-001-20231206 gcc nios2 randconfig-002-20231206 gcc openrisc allmodconfig gcc openrisc allnoconfig gcc openrisc allyesconfig gcc openriscdefconfig gcc parisc allmodconfig gcc pariscallnoconfig gcc parisc allyesconfig gcc parisc defconfig gcc pariscrandconfig-001-20231206 gcc pariscrandconfig-002-20231206 gcc parisc64defconfig gcc powerpc acadia_defconfig clang powerpc akebono_defconfig clang powerpc allmodconfig clang powerpc allnoconfig gcc powerpc allyesconfig clang powerpc canyonlands_defconfig gcc powerpc mgcoge_defconfig gcc powerpc mpc837x_rdb_defconfig gcc powerpc ps3_defconfig gcc powerpc randconfig-001-20231206 clang powerpc randconfig-002-20231206 clang powerpc randconfig-003-20231206 clang powerpc tqm5200_defconfig clang powerpc tqm8548_defconfig gcc powerpc64 randconfig-001-20231206 clang powerpc64 randconfig-002-20231206 clang powerpc64 randconfig-003-20231206 clang riscvallmodconfig gcc riscvallyesconfig gcc riscv defconfig gcc riscv rv32_defconfig clang s390 allnoconfig gcc s390defconfig gcc s390 randconfig-001-20231206 gcc
Re: [PATCH] scsi: ibmvscsi: replace deprecated strncpy with strscpy
Michael, >> strncpy() is deprecated for use on NUL-terminated destination strings >> [1] and as such we should prefer more robust and less ambiguous string >> interfaces. > I gave it a quick boot, no issues. > > Tested-by: Michael Ellerman (powerpc) Applied to 6.8/scsi-staging, thanks! -- Martin K. Petersen Oracle Linux Engineering
Re: [PATCH] scsi: ibmvfc: replace deprecated strncpy with strscpy
Kees, > On Mon, Oct 30, 2023 at 07:04:33PM +, Justin Stitt wrote: >> strncpy() is deprecated for use on NUL-terminated destination strings >> [1] and as such we should prefer more robust and less ambiguous string >> interfaces. > Yeah, this conversion looks correct to me too. > > Reviewed-by: Kees Cook Applied to 6.8/scsi-staging, thanks! -- Martin K. Petersen Oracle Linux Engineering
Re: [PATCH] scsi: ipr: Remove obsolete check for old CPUs
Michael, > The IPR driver has a routine to check whether it's running on certain > CPU versions and if so whether the adapter is supported on that CPU. Applied to 6.8/scsi-staging, thanks! -- Martin K. Petersen Oracle Linux Engineering
Re: [PATCH 1/6] x86: Use PCI_HEADER_TYPE_* instead of literals
Bjorn, > So I kept these in the PCI tree: > > 420ac76610d7 ("scsi: lpfc: Use PCI_HEADER_TYPE_MFD instead of literal") I merged this without seeing your note but I haven't pushed yet so I'll just drop the commit. -- Martin K. Petersen Oracle Linux Engineering
Re: [PATCH] i2c: cpm: Fix data type
Hi Christophe, On Tue, Dec 05, 2023 at 07:16:53PM +0100, Christophe Leroy wrote: > sparse reports an error on some data that gets converted from be32. > > That's because that data is typed u32 instead of __be32. > > Fix it. the reason for this sparse error is that the data variables is then parsed with a be32_to_cpup() and I think that's not necessary. I think the real fix here is to not use be32_to_cpup(). Andi
[PATCH] tty: hvc: dcc: Check for TXfull condition while setting up early console
Refer ARM DDI 0487I.a ID081822, D17.3.8, DBGDTRTX_EL0, "If TXfull is set to 1, set DTRRX and DTRTX to UNKNOWN" Thus one should always check for TXfull condition before hvc can be used as an early console. This is similar to what is being done today in hvc_dcc_console_init() and hvc_dcc_init(). The count 0x400 has been obtained from uboot (v2024.01-rc3) drivers/serial/arm_dcc.c "TIMEOUT_COUNT". It reads the dcc status and waits for 0x400 times for the TX Fifo to be available before returning an error. Thus, it will prevent DCC to be used as early console. Signed-off-by: Ayan Kumar Halder --- drivers/tty/hvc/hvc_dcc.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c index 1751108cf763..136381bec7cd 100644 --- a/drivers/tty/hvc/hvc_dcc.c +++ b/drivers/tty/hvc/hvc_dcc.c @@ -47,6 +47,14 @@ static void dcc_early_write(struct console *con, const char *s, unsigned n) static int __init dcc_early_console_setup(struct earlycon_device *device, const char *opt) { + unsigned int count = 0x400; + + while (--count && (__dcc_getstatus() & DCC_STATUS_TX)) + cpu_relax(); + + if (__dcc_getstatus() & DCC_STATUS_TX) + return -ENODEV; + device->con->write = dcc_early_write; return 0; -- 2.25.1
Re: [PATCH] MAINTAINERS: powerpc: Transfer PPC83XX to Christophe
On Tue, 2023-12-05 at 16:12 +1100, Michael Ellerman wrote: > Christophe volunteered[1] to maintain PPC83XX. > > 1: > https://lore.kernel.org/all/7b1bf4dc-d09d-35b8-f4df-16bf00429...@csgroup.eu/ > > Signed-off-by: Michael Ellerman > --- > MAINTAINERS | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 562d048863ee..d4efe48cc36a 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -12287,21 +12287,21 @@ S:Orphan > F: arch/powerpc/platforms/40x/ > F: arch/powerpc/platforms/44x/ > > -LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX > +LINUX FOR POWERPC EMBEDDED PPC85XX > M: Scott Wood > L: linuxppc-dev@lists.ozlabs.org > S: Odd fixes > T: git > git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux.git > F: Documentation/devicetree/bindings/cache/freescale-l2cache.txt > F: Documentation/devicetree/bindings/powerpc/fsl/ > -F: arch/powerpc/platforms/83xx/ > F: arch/powerpc/platforms/85xx/ > > -LINUX FOR POWERPC EMBEDDED PPC8XX > +LINUX FOR POWERPC EMBEDDED PPC8XX AND PPC83XX > M: Christophe Leroy > L: linuxppc-dev@lists.ozlabs.org > S: Maintained > F: arch/powerpc/platforms/8xx/ > +F: arch/powerpc/platforms/83xx/ Acked-by: Crystal Wood -Crystal
Re: [PATCH V4] tools/perf: Add perf binary dependent rule for shellcheck log in Makefile.perf
On Tue, Dec 5, 2023 at 1:50 PM Arnaldo Carvalho de Melo wrote: > > Em Mon, Nov 27, 2023 at 11:12:57AM +, James Clark escreveu: > > On 23/11/2023 16:02, Athira Rajeev wrote: > > > --- a/tools/perf/Makefile.perf > > > @@ -1134,6 +1152,7 @@ bpf-skel-clean: > > > $(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS) > > > > > > clean:: $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean > > > $(LIBSYMBOL)-clean $(LIBPERF)-clean fixdep-clean python-clean > > > bpf-skel-clean tests-coresight-targets-clean > > > + $(Q)$(MAKE) -f $(srctree)/tools/perf/tests/Makefile.tests clean > > > $(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) > > > $(OUTPUT)perf-archive $(OUTPUT)perf-iostat $(LANG_BINDINGS) > > > $(Q)find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' > > > -delete -o -name '\.*.d' -delete > > > $(Q)$(RM) $(OUTPUT).config-detected > > While merging perf-tools-next with torvalds/master I noticed that maybe > we better have the above added line as: > > + $(call QUIET_CLEAN, tests) $(Q)$(MAKE) -f > $(srctree)/tools/perf/tests/Makefile.tests clean > > No? > > Anyway I'm merging as-is, but it just hit my eye while merging, > > - Arnaldo Makefile.tests was removed in these recent patches adding support for the OUTPUT directory: https://lore.kernel.org/lkml/9c33887f-8a88-4973-8593-7936e36af...@linux.vnet.ibm.com/ Thanks, Ian
Re: [PATCH V4] tools/perf: Add perf binary dependent rule for shellcheck log in Makefile.perf
Em Mon, Nov 27, 2023 at 11:12:57AM +, James Clark escreveu: > On 23/11/2023 16:02, Athira Rajeev wrote: > > --- a/tools/perf/Makefile.perf > > @@ -1134,6 +1152,7 @@ bpf-skel-clean: > > $(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS) > > > > clean:: $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean > > $(LIBSYMBOL)-clean $(LIBPERF)-clean fixdep-clean python-clean > > bpf-skel-clean tests-coresight-targets-clean > > + $(Q)$(MAKE) -f $(srctree)/tools/perf/tests/Makefile.tests clean > > $(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) > > $(OUTPUT)perf-archive $(OUTPUT)perf-iostat $(LANG_BINDINGS) > > $(Q)find $(or $(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' > > -delete -o -name '\.*.d' -delete > > $(Q)$(RM) $(OUTPUT).config-detected While merging perf-tools-next with torvalds/master I noticed that maybe we better have the above added line as: + $(call QUIET_CLEAN, tests) $(Q)$(MAKE) -f $(srctree)/tools/perf/tests/Makefile.tests clean No? Anyway I'm merging as-is, but it just hit my eye while merging, - Arnaldo
[RFC PATCH 3/3] powerpc/fadump: pass additional parameters when fadump is active
Append the additional parameters passed/set in the dedicated parameter area (RTAS_FADUMP_PARAM_AREA) to bootargs in fadump capture kernel. Signed-off-by: Hari Bathini --- arch/powerpc/include/asm/fadump.h | 2 ++ arch/powerpc/kernel/fadump.c | 34 +++ arch/powerpc/kernel/prom.c| 3 +++ 3 files changed, 39 insertions(+) diff --git a/arch/powerpc/include/asm/fadump.h b/arch/powerpc/include/asm/fadump.h index 526a6a647312..ef40c9b6972a 100644 --- a/arch/powerpc/include/asm/fadump.h +++ b/arch/powerpc/include/asm/fadump.h @@ -19,12 +19,14 @@ extern int is_fadump_active(void); extern int should_fadump_crash(void); extern void crash_fadump(struct pt_regs *, const char *); extern void fadump_cleanup(void); +extern void fadump_append_bootargs(void); #else /* CONFIG_FA_DUMP */ static inline int is_fadump_active(void) { return 0; } static inline int should_fadump_crash(void) { return 0; } static inline void crash_fadump(struct pt_regs *regs, const char *str) { } static inline void fadump_cleanup(void) { } +static inline void fadump_append_bootargs(void) { } #endif /* !CONFIG_FA_DUMP */ #if defined(CONFIG_FA_DUMP) || defined(CONFIG_PRESERVE_FA_DUMP) diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c index 98f089747ac9..9b1601f99f72 100644 --- a/arch/powerpc/kernel/fadump.c +++ b/arch/powerpc/kernel/fadump.c @@ -133,6 +133,40 @@ static int __init fadump_cma_init(void) static int __init fadump_cma_init(void) { return 1; } #endif /* CONFIG_CMA */ +/* + * Additional parameters meant for capture kernel are placed in a dedicated area. + * If this is capture kernel boot, append these parameters to bootargs. + */ +void __init fadump_append_bootargs(void) +{ + char *append_args; + size_t len; + + if (!fw_dump.dump_active || !fw_dump.param_area_supported || !fw_dump.param_area) + return; + + /* TODO: What to do if this overlaps with reserve area (radix case?) */ + if (memblock_reserve(fw_dump.param_area, COMMAND_LINE_SIZE)) { + pr_warn("WARNING: Can't use additional parameters area!\n"); + fw_dump.param_area = 0; + return; + } + + append_args = (char *)fw_dump.param_area; + len = strlen(boot_command_line); + + /* +* Too late to fail even if cmdline size exceeds. Truncate additional parameters +* to cmdline size and proceed anyway. +*/ + if (len + strlen(append_args) >= COMMAND_LINE_SIZE - 1) + pr_warn("WARNING: Appending parameters exceeds cmdline size. Truncating!\n"); + + pr_debug("Cmdline: %s\n", boot_command_line); + snprintf(boot_command_line + len, COMMAND_LINE_SIZE - len, " %s", append_args); + pr_info("Updated cmdline: %s\n", boot_command_line); +} + /* Scan the Firmware Assisted dump configuration details. */ int __init early_init_dt_scan_fw_dump(unsigned long node, const char *uname, int depth, void *data) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 0b5878c3125b..00a03d476cb9 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -791,6 +791,9 @@ void __init early_init_devtree(void *params) */ of_scan_flat_dt(early_init_dt_scan_chosen_ppc, boot_command_line); + /* Append additional parameters passed for fadump capture kernel */ + fadump_append_bootargs(); + /* Scan memory nodes and rebuild MEMBLOCKs */ early_init_dt_scan_root(); early_init_dt_scan_memory_ppc(); -- 2.43.0
[RFC PATCH 2/3] powerpc/fadump: pass additional parameters to dump capture kernel
For fadump case, passing additional parameters to dump capture kernel helps in minimizing the memory footprint for it and also provides the flexibility to disable components/modules, like hugepages, that are hindering the boot process of the special dump capture environment. Set up a dedicated parameter area to be passed to the capture kernel. This area type is defined as RTAS_FADUMP_PARAM_AREA. Sysfs attribute '/sys/kernel/fadump/bootargs_append' is exported to the userspace to specify the additional parameters to be passed to the capture kernel Signed-off-by: Hari Bathini --- arch/powerpc/include/asm/fadump-internal.h | 3 + arch/powerpc/kernel/fadump.c | 80 arch/powerpc/platforms/powernv/opal-fadump.c | 6 +- arch/powerpc/platforms/pseries/rtas-fadump.c | 35 - arch/powerpc/platforms/pseries/rtas-fadump.h | 11 ++- 5 files changed, 126 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/include/asm/fadump-internal.h b/arch/powerpc/include/asm/fadump-internal.h index b3956c400519..81629226b15f 100644 --- a/arch/powerpc/include/asm/fadump-internal.h +++ b/arch/powerpc/include/asm/fadump-internal.h @@ -97,6 +97,8 @@ struct fw_dump { unsigned long cpu_notes_buf_vaddr; unsigned long cpu_notes_buf_size; + unsigned long param_area; + /* * Maximum size supported by firmware to copy from source to * destination address per entry. @@ -111,6 +113,7 @@ struct fw_dump { unsigned long dump_active:1; unsigned long dump_registered:1; unsigned long nocma:1; + unsigned long param_area_supported:1; struct fadump_ops *ops; }; diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c index 757681658dda..98f089747ac9 100644 --- a/arch/powerpc/kernel/fadump.c +++ b/arch/powerpc/kernel/fadump.c @@ -1470,6 +1470,7 @@ static ssize_t mem_reserved_show(struct kobject *kobj, return sprintf(buf, "%ld\n", fw_dump.reserve_dump_area_size); } + static ssize_t registered_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) @@ -1477,6 +1478,43 @@ static ssize_t registered_show(struct kobject *kobj, return sprintf(buf, "%d\n", fw_dump.dump_registered); } +static ssize_t bootargs_append_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + return sprintf(buf, "%s\n", (char *)__va(fw_dump.param_area)); +} + +static ssize_t bootargs_append_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + char *params; + + if (!fw_dump.fadump_enabled || fw_dump.dump_active) + return -EPERM; + + if (count >= COMMAND_LINE_SIZE) + return -EINVAL; + + /* +* Fail here instead of handling this scenario with +* some silly workaround in capture kernel. +*/ + if (saved_command_line_len + count >= COMMAND_LINE_SIZE) { + pr_err("Appending parameters exceeds cmdline size!\n"); + return -ENOSPC; + } + + params = __va(fw_dump.param_area); + strscpy_pad(params, buf, COMMAND_LINE_SIZE); + /* Remove newline character at the end. */ + if (params[count-1] == '\n') + params[count-1] = '\0'; + + return count; +} + static ssize_t registered_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) @@ -1535,6 +1573,7 @@ static struct kobj_attribute release_attr = __ATTR_WO(release_mem); static struct kobj_attribute enable_attr = __ATTR_RO(enabled); static struct kobj_attribute register_attr = __ATTR_RW(registered); static struct kobj_attribute mem_reserved_attr = __ATTR_RO(mem_reserved); +static struct kobj_attribute bootargs_append_attr = __ATTR_RW(bootargs_append); static struct attribute *fadump_attrs[] = { _attr.attr, @@ -1611,6 +1650,46 @@ static void __init fadump_init_files(void) return; } +/* + * Reserve memory to store additional parameters to be passed + * for fadump/capture kernel. + */ +static void fadump_setup_param_area(void) +{ + phys_addr_t range_start, range_end; + + if (!fw_dump.param_area_supported || fw_dump.dump_active) + return; + + /* This memory can't be used by PFW or bootloader as it is shared across kernels */ + if (radix_enabled()) { + /* +* Anywhere in the upper half should be good enough as all memory +* is accessible in real mode. +*/ + range_start = memblock_end_of_DRAM() / 2; + range_end = memblock_end_of_DRAM(); + } else { + /* +
[RFC PATCH 1/3] powerpc/pseries/fadump: add support for multiple boot memory regions
From: Sourabh Jain Currently, fadump on pseries assumes a single boot memory region even though f/w supports more than one boot memory region. Add support for more boot memory regions to make the implementation flexible for any enhancements that introduce other region types. For this, rtas memory structure for fadump is updated to have multiple boot memory regions instead of just one. Additionally, methods responsible for creating the fadump memory structure during both the first and second kernel boot have been modified to take these multiple boot memory regions into account. Also, a new callback has been added to the fadump_ops structure to get the maximum boot memory regions supported by the platform. Signed-off-by: Sourabh Jain Signed-off-by: Hari Bathini --- arch/powerpc/include/asm/fadump-internal.h | 2 +- arch/powerpc/kernel/fadump.c | 27 +- arch/powerpc/platforms/powernv/opal-fadump.c | 8 + arch/powerpc/platforms/pseries/rtas-fadump.c | 258 --- arch/powerpc/platforms/pseries/rtas-fadump.h | 26 +- 5 files changed, 199 insertions(+), 122 deletions(-) diff --git a/arch/powerpc/include/asm/fadump-internal.h b/arch/powerpc/include/asm/fadump-internal.h index 27f9e11eda28..b3956c400519 100644 --- a/arch/powerpc/include/asm/fadump-internal.h +++ b/arch/powerpc/include/asm/fadump-internal.h @@ -129,6 +129,7 @@ struct fadump_ops { struct seq_file *m); void(*fadump_trigger)(struct fadump_crash_info_header *fdh, const char *msg); + int (*fadump_max_boot_mem_rgns)(void); }; /* Helper functions */ @@ -136,7 +137,6 @@ s32 __init fadump_setup_cpu_notes_buf(u32 num_cpus); void fadump_free_cpu_notes_buf(void); u32 *__init fadump_regs_to_elf_notes(u32 *buf, struct pt_regs *regs); void __init fadump_update_elfcore_header(char *bufp); -bool is_fadump_boot_mem_contiguous(void); bool is_fadump_reserved_mem_contiguous(void); #else /* !CONFIG_PRESERVE_FA_DUMP */ diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c index d14eda1e8589..757681658dda 100644 --- a/arch/powerpc/kernel/fadump.c +++ b/arch/powerpc/kernel/fadump.c @@ -222,28 +222,6 @@ static bool is_fadump_mem_area_contiguous(u64 d_start, u64 d_end) return ret; } -/* - * Returns true, if there are no holes in boot memory area, - * false otherwise. - */ -bool is_fadump_boot_mem_contiguous(void) -{ - unsigned long d_start, d_end; - bool ret = false; - int i; - - for (i = 0; i < fw_dump.boot_mem_regs_cnt; i++) { - d_start = fw_dump.boot_mem_addr[i]; - d_end = d_start + fw_dump.boot_mem_sz[i]; - - ret = is_fadump_mem_area_contiguous(d_start, d_end); - if (!ret) - break; - } - - return ret; -} - /* * Returns true, if there are no holes in reserved memory area, * false otherwise. @@ -389,10 +367,11 @@ static unsigned long __init get_fadump_area_size(void) static int __init add_boot_mem_region(unsigned long rstart, unsigned long rsize) { + int max_boot_mem_rgns = fw_dump.ops->fadump_max_boot_mem_rgns(); int i = fw_dump.boot_mem_regs_cnt++; - if (fw_dump.boot_mem_regs_cnt > FADUMP_MAX_MEM_REGS) { - fw_dump.boot_mem_regs_cnt = FADUMP_MAX_MEM_REGS; + if (fw_dump.boot_mem_regs_cnt > max_boot_mem_rgns) { + fw_dump.boot_mem_regs_cnt = max_boot_mem_rgns; return 0; } diff --git a/arch/powerpc/platforms/powernv/opal-fadump.c b/arch/powerpc/platforms/powernv/opal-fadump.c index 964f464b1b0e..fa26c21a08d9 100644 --- a/arch/powerpc/platforms/powernv/opal-fadump.c +++ b/arch/powerpc/platforms/powernv/opal-fadump.c @@ -615,6 +615,13 @@ static void opal_fadump_trigger(struct fadump_crash_info_header *fdh, pr_emerg("No backend support for MPIPL!\n"); } +/* FADUMP_MAX_MEM_REGS or lower */ +static int opal_fadump_max_boot_mem_rgns(void) +{ + return FADUMP_MAX_MEM_REGS; + +} + static struct fadump_ops opal_fadump_ops = { .fadump_init_mem_struct = opal_fadump_init_mem_struct, .fadump_get_metadata_size = opal_fadump_get_metadata_size, @@ -627,6 +634,7 @@ static struct fadump_ops opal_fadump_ops = { .fadump_process = opal_fadump_process, .fadump_region_show = opal_fadump_region_show, .fadump_trigger = opal_fadump_trigger, + .fadump_max_boot_mem_rgns = opal_fadump_max_boot_mem_rgns, }; void __init opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node) diff --git a/arch/powerpc/platforms/pseries/rtas-fadump.c b/arch/powerpc/platforms/pseries/rtas-fadump.c index b5853e9fcc3c..1b05b4cefdfd 100644 --- a/arch/powerpc/platforms/pseries/rtas-fadump.c +++ b/arch/powerpc/platforms/pseries/rtas-fadump.c @@ -29,9 +29,6 @@ static const
[RFC PATCH 0/3] powerpc/fadump: pass additional args to dump capture kernel
While fadump is a more reliable alternative to kdump dump capturing method, it doesn't support passing additional parameters. Having such support is desirable for two major reasons: 1. It helps minimize the memory consumption of fadump dump capture kernel by disabling features that consume considerable amount of memory but have little significance for dump capture environment (eg. numa, cma, cgroup, etc.) 2. It helps disable such features/components in dump capture kernel that are unstable and/or are being debugged. This patch series adds support to pass additional parameters to fadump capture kernel to make it more desirable. For this, a dedicated area is passed between production kernel and capture kerenl to pass these additional parameters. This support is enabled only on pseries as of now. The dedicated area is referred to as RTAS_FADUMP_PARAM_AREA. In radix MMU mode, this dedicated area can be anywhere but in case of hash MMU, it can only be in the first memory block to be accessible during early boot. Enabling this feature support in both radix and hash MMU modes but in hash MMU only when RMA size is 768MB or more to avoid complex memory real estate with FW components. The first patch adds support for multiple boot memory regions to make addition of any new region types simpler. The second patch sets up the parameter (dedicated) area to be passed to the capture kernel. /sys/kernel/fadump/bootargs_append is exported to the userspace to specify the additional parameters to be passed to the capture kernel. The last patch appends the parameters to bootargs during capture kernel boot. Hari Bathini (2): powerpc/fadump: pass additional parameters to dump capture kernel powerpc/fadump: pass additional parameters when fadump is active Sourabh Jain (1): powerpc/pseries/fadump: add support for multiple boot memory regions arch/powerpc/include/asm/fadump-internal.h | 5 +- arch/powerpc/include/asm/fadump.h| 2 + arch/powerpc/kernel/fadump.c | 141 +++-- arch/powerpc/kernel/prom.c | 3 + arch/powerpc/platforms/powernv/opal-fadump.c | 14 +- arch/powerpc/platforms/pseries/rtas-fadump.c | 293 +-- arch/powerpc/platforms/pseries/rtas-fadump.h | 29 +- 7 files changed, 360 insertions(+), 127 deletions(-) -- 2.43.0
Re: [PATCH 5.15 00/67] 5.15.142-rc1 review
On Tue, Dec 05, 2023 at 10:18:49PM +0530, Naresh Kamboju wrote: > On Tue, 5 Dec 2023 at 09:10, Greg Kroah-Hartman > wrote: > > > > This is the start of the stable review cycle for the 5.15.142 release. > > There are 67 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 Thu, 07 Dec 2023 03:14:57 +. > > 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.15.142-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.15.y > > and the diffstat can be found below. > > > > thanks, > > > > greg k-h > > > Following powerpc build failures noticed. > > * powerpc, build > - clang-17-defconfig - FAILED > - gcc-12-defconfig - FAILED > - gcc-8-defconfig - FAILED > > build error: > --- > arch/powerpc/platforms/pseries/iommu.c: In function 'find_existing_ddw': > arch/powerpc/platforms/pseries/iommu.c:908:49: error: 'struct dma_win' > has no member named 'direct' > 908 | *direct_mapping = window->direct; > | ^~ > > suspected commit: > powerpc/pseries/iommu: enable_ddw incorrectly returns direct mapping > for SR-IOV device > [ Upstream commit 3bf983e4e93ce8e6d69e9d63f52a66ec0856672e ] > > Reported-by: Linux Kernel Functional Testing Thanks, now dropped from 5.15.y and 6.1.y
[PATCH] i2c: cpm: Fix data type
sparse reports an error on some data that gets converted from be32. That's because that data is typed u32 instead of __be32. Fix it. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202312042210.ql4da8av-...@intel.com/ Signed-off-by: Christophe Leroy --- drivers/i2c/busses/i2c-cpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 9a664abf734d..077be367b382 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -634,7 +634,7 @@ static int cpm_i2c_probe(struct platform_device *ofdev) { int result, len; struct cpm_i2c *cpm; - const u32 *data; + const __be32 *data; cpm = kzalloc(sizeof(struct cpm_i2c), GFP_KERNEL); if (!cpm) -- 2.41.0
Re: [PATCH v4 05/13] powerpc/rtas: Facilitate high-level call sequences
Nathan Lynch writes: > Michael Ellerman writes: >> Nathan Lynch writes: >>> Michael Ellerman writes: Nathan Lynch writes: > Michael Ellerman writes: >> Nathan Lynch via B4 Relay >> writes: >>> From: Nathan Lynch >>> >>> On RTAS platforms there is a general restriction that the OS must not >>> enter RTAS on more than one CPU at a time. This low-level >>> serialization requirement is satisfied by holding a spin >>> lock (rtas_lock) across most RTAS function invocations. >> ... >>> diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c >>> index 1fc0b3fffdd1..52f2242d0c28 100644 >>> --- a/arch/powerpc/kernel/rtas.c >>> +++ b/arch/powerpc/kernel/rtas.c >>> @@ -581,6 +652,28 @@ static const struct rtas_function >>> *rtas_token_to_function(s32 token) >>> return NULL; >>> } >>> >>> +static void __rtas_function_lock(struct rtas_function *func) >>> +{ >>> + if (func && func->lock) >>> + mutex_lock(func->lock); >>> +} >> >> This is obviously going to defeat most static analysis tools. > > I guess it's not that obvious to me :-) Is it because the mutex_lock() > is conditional? I'll improve this if it's possible. Well maybe I'm not giving modern static analysis tools enough credit :) But what I mean that it's not easy to reason about what the function does in isolation. ie. all you can say is that it may or may not lock a mutex, and you can't say which mutex. >>> >>> I've pulled the thread on this a little bit and here is what I can do: >>> >>> * Discard rtas_lock_function() and rtas_unlock_function() and make the >>> function mutexes extern as needed. As of now only >>> rtas_ibm_get_vpd_lock will need to be exposed. This enables us to put >>> __acquires(), __releases(), and __must_hold() annotations in >>> papr-vpd.c since it explicitly manipulates the mutex. >>> >>> * Then sys_rtas() becomes the only site that needs >>> __rtas_function_lock() and __rtas_function_unlock(), which can be >>> open-coded and commented (and, one hopes, not emulated elsewhere). >>> >>> This will look something like: >>> >>> SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs) >>> { >>> struct rtas_function *func = rtas_token_to_function(token); >>> >>> if (func->lock) >>> mutex_lock(func->lock); >>> >>> [ ... acquire rtas_lock, enter RTAS, fetch any errors ... ] >>> >>> if (func->lock) >>> mutex_unlock(func->lock); >>> >>> The indirection seems unavoidable since we're working backwards from a >>> token value (supplied by the user and not known at build time) to the >>> function descriptor. >>> >>> Is that tolerable for now? >> >> Yeah. Thanks for looking into it. >> >> I wasn't unhappy with the original version, but just slightly uneasy >> about the locking via pointer. >> >> But that new proposal sounds good, more code will have static lock >> annotations, and only sys_rtas() which is already weird, will have the >> dynamic stuff. > > OK, I'll work that up then. Well, apparently the annotations aren't useful with mutexes; see these threads: https://lore.kernel.org/all/8e8d93ee2125c739caabe5986f40fa2156c8b4ce.1579893447.git.jbi.oct...@gmail.com/ https://lore.kernel.org/all/20200601184552.23128-5-jbi.oct...@gmail.com/ And indeed I can't get sparse to accept them when added to the papr-vpd code: $ make C=2 arch/powerpc/platforms/pseries/papr-vpd.o CHECK scripts/mod/empty.c CALLscripts/checksyscalls.sh CHECK arch/powerpc/platforms/pseries/papr-vpd.c arch/powerpc/platforms/pseries/papr-vpd.c:235:13: warning: context imbalance in 'vpd_sequence_begin' - wrong count at exit arch/powerpc/platforms/pseries/papr-vpd.c:269:13: warning: context imbalance in 'vpd_sequence_end' - wrong count at exit I don't think it's my own mistake since I see existing code with the same problem, such as net/core/sock.c: static void *proto_seq_start(struct seq_file *seq, loff_t *pos) __acquires(proto_list_mutex) { mutex_lock(_list_mutex); return seq_list_start_head(_list, *pos); } static void proto_seq_stop(struct seq_file *seq, void *v) __releases(proto_list_mutex) { mutex_unlock(_list_mutex); } which yields: net/core/sock.c:4018:13: warning: context imbalance in 'proto_seq_start' - wrong count at exit net/core/sock.c:4030:13: warning: context imbalance in 'proto_seq_stop' - wrong count at exit So I'll give up on static annotations for this series and look for opportunities to add lockdep_assert_held() etc.
Re: [PATCH v13 6/6] powerpc: add crash memory hotplug support
Hi Sourabh, kernel test robot noticed the following build errors: [auto build test ERROR on powerpc/next] [also build test ERROR on powerpc/fixes tip/x86/core akpm-mm/mm-everything linus/master v6.7-rc4 next-20231205] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Sourabh-Jain/crash-make-CPU-and-Memory-hotplug-support-reporting-flexible/20231204-143305 base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next patch link: https://lore.kernel.org/r/20231204053253.25305-7-sourabhjain%40linux.ibm.com patch subject: [PATCH v13 6/6] powerpc: add crash memory hotplug support config: powerpc64-randconfig-001-20231205 (https://download.01.org/0day-ci/archive/20231206/202312060059.jitejl8b-...@intel.com/config) compiler: powerpc64-linux-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231206/202312060059.jitejl8b-...@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202312060059.jitejl8b-...@intel.com/ All errors (new ones prefixed by >>): arch/powerpc/kexec/core_64.c: In function 'arch_crash_get_elfcorehdr_size': >> arch/powerpc/kexec/core_64.c:595:33: error: implicit declaration of function >> 'memory_hotplug_max' [-Werror=implicit-function-declaration] 595 | elf_phdr_cnt += memory_hotplug_max() / (2 * drmem_lmb_size()); | ^~ cc1: some warnings being treated as errors vim +/memory_hotplug_max +595 arch/powerpc/kexec/core_64.c 579 580 /* 581 * Advertise preferred elfcorehdr size to userspace via 582 * /sys/kernel/crash_elfcorehdr_size sysfs interface. 583 */ 584 unsigned int arch_crash_get_elfcorehdr_size(void) 585 { 586 unsigned int sz; 587 unsigned long elf_phdr_cnt; 588 589 /* Program header for CPU notes and vmcoreinfo */ 590 elf_phdr_cnt = 2; 591 if (IS_ENABLED(CONFIG_MEMORY_HOTPLUG)) 592 /* In the worst case, a Phdr is needed for every other LMB to be 593 * represented as an individual crash range. 594 */ > 595 elf_phdr_cnt += memory_hotplug_max() / (2 * > drmem_lmb_size()); 596 597 /* Do not cross the max limit */ 598 if (elf_phdr_cnt > PN_XNUM) 599 elf_phdr_cnt = PN_XNUM; 600 601 sz = sizeof(struct elfhdr) + (elf_phdr_cnt * sizeof(Elf64_Phdr)); 602 return sz; 603 } 604 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Re: [PATCH 5.15 00/67] 5.15.142-rc1 review
On Tue, 5 Dec 2023 at 09:10, Greg Kroah-Hartman wrote: > > This is the start of the stable review cycle for the 5.15.142 release. > There are 67 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 Thu, 07 Dec 2023 03:14:57 +. > 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.15.142-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.15.y > and the diffstat can be found below. > > thanks, > > greg k-h Following powerpc build failures noticed. * powerpc, build - clang-17-defconfig - FAILED - gcc-12-defconfig - FAILED - gcc-8-defconfig - FAILED build error: --- arch/powerpc/platforms/pseries/iommu.c: In function 'find_existing_ddw': arch/powerpc/platforms/pseries/iommu.c:908:49: error: 'struct dma_win' has no member named 'direct' 908 | *direct_mapping = window->direct; | ^~ suspected commit: powerpc/pseries/iommu: enable_ddw incorrectly returns direct mapping for SR-IOV device [ Upstream commit 3bf983e4e93ce8e6d69e9d63f52a66ec0856672e ] Reported-by: Linux Kernel Functional Testing Links: - https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.15.y/build/v5.15.141-68-gbff845be423f/testrun/21492943/suite/build/test/gcc-12-defconfig/details/ - https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-5.15.y/build/v5.15.141-68-gbff845be423f/testrun/21492943/suite/build/test/gcc-12-defconfig/history/ -- Linaro LKFT https://lkft.linaro.org
[PATCH v2 17/17] soc: fsl: cpm1: qmc: Introduce functions to change timeslots at runtime
Introduce qmc_chan_{get,set}_ts_info() function to allow timeslots modification at runtime. The modification is provided using qmc_chan_set_ts_info() and will be applied on next qmc_chan_start(). qmc_chan_set_ts_info() must be called with the channel rx and/or tx stopped. Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 51 include/soc/fsl/qe/qmc.h | 10 2 files changed, 61 insertions(+) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index 45d9cb40a118..f498db9abe35 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -290,6 +290,57 @@ int qmc_chan_get_info(struct qmc_chan *chan, struct qmc_chan_info *info) } EXPORT_SYMBOL(qmc_chan_get_info); +int qmc_chan_get_ts_info(struct qmc_chan *chan, struct qmc_chan_ts_info *ts_info) +{ + unsigned long flags; + + spin_lock_irqsave(>ts_lock, flags); + + ts_info->rx_ts_mask_avail = chan->rx_ts_mask_avail; + ts_info->tx_ts_mask_avail = chan->tx_ts_mask_avail; + ts_info->rx_ts_mask = chan->rx_ts_mask; + ts_info->tx_ts_mask = chan->tx_ts_mask; + + spin_unlock_irqrestore(>ts_lock, flags); + + return 0; +} +EXPORT_SYMBOL(qmc_chan_get_ts_info); + +int qmc_chan_set_ts_info(struct qmc_chan *chan, const struct qmc_chan_ts_info *ts_info) +{ + unsigned long flags; + int ret; + + /* Only a subset of available timeslots is allowed */ + if ((ts_info->rx_ts_mask & chan->rx_ts_mask_avail) != ts_info->rx_ts_mask) + return -EINVAL; + if ((ts_info->tx_ts_mask & chan->tx_ts_mask_avail) != ts_info->tx_ts_mask) + return -EINVAL; + + /* In case of common rx/tx table, rx/tx masks must be identical */ + if (chan->qmc->is_tsa_64rxtx) { + if (ts_info->rx_ts_mask != ts_info->tx_ts_mask) + return -EINVAL; + } + + spin_lock_irqsave(>ts_lock, flags); + + if ((chan->tx_ts_mask != ts_info->tx_ts_mask && !chan->is_tx_stopped) || + (chan->rx_ts_mask != ts_info->rx_ts_mask && !chan->is_rx_stopped)) { + dev_err(chan->qmc->dev, "Channel rx and/or tx not stopped\n"); + ret = -EBUSY; + } else { + chan->tx_ts_mask = ts_info->tx_ts_mask; + chan->rx_ts_mask = ts_info->rx_ts_mask; + ret = 0; + } + spin_unlock_irqrestore(>ts_lock, flags); + + return ret; +} +EXPORT_SYMBOL(qmc_chan_set_ts_info); + int qmc_chan_set_param(struct qmc_chan *chan, const struct qmc_chan_param *param) { if (param->mode != chan->mode) diff --git a/include/soc/fsl/qe/qmc.h b/include/soc/fsl/qe/qmc.h index 166484bb4294..2a333fc1ea81 100644 --- a/include/soc/fsl/qe/qmc.h +++ b/include/soc/fsl/qe/qmc.h @@ -40,6 +40,16 @@ struct qmc_chan_info { int qmc_chan_get_info(struct qmc_chan *chan, struct qmc_chan_info *info); +struct qmc_chan_ts_info { + u64 rx_ts_mask_avail; + u64 tx_ts_mask_avail; + u64 rx_ts_mask; + u64 tx_ts_mask; +}; + +int qmc_chan_get_ts_info(struct qmc_chan *chan, struct qmc_chan_ts_info *ts_info); +int qmc_chan_set_ts_info(struct qmc_chan *chan, const struct qmc_chan_ts_info *ts_info); + struct qmc_chan_param { enum qmc_mode mode; union { -- 2.43.0
[PATCH v2 16/17] soc: fsl: cpm1: qmc: Remove timeslots handling from setup_chan()
Timeslots setting is done at channel start() and stop(). There is no more need to do that during setup_chan(). Simply remove timeslot setting from setup_chan(). Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 28 1 file changed, 28 deletions(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index bc72c1bc0ec4..45d9cb40a118 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -723,30 +723,6 @@ static int qmc_chan_setup_tsa_rx(struct qmc_chan *chan, bool enable) return qmc_chan_setup_tsa_32rx(chan, , enable); } -static int qmc_chan_setup_tsa(struct qmc_chan *chan, bool enable) -{ - struct tsa_serial_info info; - int ret; - - /* Retrieve info from the TSA related serial */ - ret = tsa_serial_get_info(chan->qmc->tsa_serial, ); - if (ret) - return ret; - - /* -* Setup one common 64 entries table or two 32 entries (one for Tx -* and one for Tx) according to assigned TS numbers. -*/ - if (chan->qmc->is_tsa_64rxtx) - return qmc_chan_setup_tsa_64rxtx(chan, , enable); - - ret = qmc_chan_setup_tsa_32rx(chan, , enable); - if (ret) - return ret; - - return qmc_chan_setup_tsa_32tx(chan, , enable); -} - static int qmc_chan_command(struct qmc_chan *chan, u8 qmc_opcode) { return cpm_command(chan->id << 2, (qmc_opcode << 4) | 0x0E); @@ -1321,10 +1297,6 @@ static int qmc_setup_chan(struct qmc *qmc, struct qmc_chan *chan) chan->qmc = qmc; - ret = qmc_chan_setup_tsa(chan, true); - if (ret) - return ret; - /* Set channel specific parameter base address */ chan->s_param = qmc->dpram + (chan->id * 64); /* 16 bd per channel (8 rx and 8 tx) */ -- 2.43.0
[PATCH v2 15/17] soc: fsl: cpm1: qmc: Handle timeslot entries at channel start() and stop()
In order to support runtime timeslot route changes, enable the channel timeslot entries at channel start() and disable them at channel stop(). Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 241 +++ 1 file changed, 195 insertions(+), 46 deletions(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index e651b3bba1ca..bc72c1bc0ec4 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -177,6 +177,7 @@ struct qmc_chan { struct qmc *qmc; void __iomem *s_param; enum qmc_mode mode; + spinlock_t ts_lock; /* Protect timeslots */ u64 tx_ts_mask_avail; u64 tx_ts_mask; u64 rx_ts_mask_avail; @@ -265,6 +266,7 @@ static void qmc_setbits32(void __iomem *addr, u32 set) int qmc_chan_get_info(struct qmc_chan *chan, struct qmc_chan_info *info) { struct tsa_serial_info tsa_info; + unsigned long flags; int ret; /* Retrieve info from the TSA related serial */ @@ -272,6 +274,8 @@ int qmc_chan_get_info(struct qmc_chan *chan, struct qmc_chan_info *info) if (ret) return ret; + spin_lock_irqsave(>ts_lock, flags); + info->mode = chan->mode; info->rx_fs_rate = tsa_info.rx_fs_rate; info->rx_bit_rate = tsa_info.rx_bit_rate; @@ -280,6 +284,8 @@ int qmc_chan_get_info(struct qmc_chan *chan, struct qmc_chan_info *info) info->tx_bit_rate = tsa_info.tx_bit_rate; info->nb_rx_ts = hweight64(chan->rx_ts_mask); + spin_unlock_irqrestore(>ts_lock, flags); + return 0; } EXPORT_SYMBOL(qmc_chan_get_info); @@ -683,6 +689,40 @@ static int qmc_chan_setup_tsa_32tx(struct qmc_chan *chan, const struct tsa_seria return 0; } +static int qmc_chan_setup_tsa_tx(struct qmc_chan *chan, bool enable) +{ + struct tsa_serial_info info; + int ret; + + /* Retrieve info from the TSA related serial */ + ret = tsa_serial_get_info(chan->qmc->tsa_serial, ); + if (ret) + return ret; + + /* Setup entries */ + if (chan->qmc->is_tsa_64rxtx) + return qmc_chan_setup_tsa_64rxtx(chan, , enable); + + return qmc_chan_setup_tsa_32tx(chan, , enable); +} + +static int qmc_chan_setup_tsa_rx(struct qmc_chan *chan, bool enable) +{ + struct tsa_serial_info info; + int ret; + + /* Retrieve info from the TSA related serial */ + ret = tsa_serial_get_info(chan->qmc->tsa_serial, ); + if (ret) + return ret; + + /* Setup entries */ + if (chan->qmc->is_tsa_64rxtx) + return qmc_chan_setup_tsa_64rxtx(chan, , enable); + + return qmc_chan_setup_tsa_32rx(chan, , enable); +} + static int qmc_chan_setup_tsa(struct qmc_chan *chan, bool enable) { struct tsa_serial_info info; @@ -719,6 +759,12 @@ static int qmc_chan_stop_rx(struct qmc_chan *chan) spin_lock_irqsave(>rx_lock, flags); + if (chan->is_rx_stopped) { + /* The channel is already stopped -> simply return ok */ + ret = 0; + goto end; + } + /* Send STOP RECEIVE command */ ret = qmc_chan_command(chan, 0x0); if (ret) { @@ -729,6 +775,15 @@ static int qmc_chan_stop_rx(struct qmc_chan *chan) chan->is_rx_stopped = true; + if (!chan->qmc->is_tsa_64rxtx || chan->is_tx_stopped) { + ret = qmc_chan_setup_tsa_rx(chan, false); + if (ret) { + dev_err(chan->qmc->dev, "chan %u: Disable tsa entries failed (%d)\n", + chan->id, ret); + goto end; + } + } + end: spin_unlock_irqrestore(>rx_lock, flags); return ret; @@ -741,6 +796,12 @@ static int qmc_chan_stop_tx(struct qmc_chan *chan) spin_lock_irqsave(>tx_lock, flags); + if (chan->is_tx_stopped) { + /* The channel is already stopped -> simply return ok */ + ret = 0; + goto end; + } + /* Send STOP TRANSMIT command */ ret = qmc_chan_command(chan, 0x1); if (ret) { @@ -751,37 +812,114 @@ static int qmc_chan_stop_tx(struct qmc_chan *chan) chan->is_tx_stopped = true; + if (!chan->qmc->is_tsa_64rxtx || chan->is_rx_stopped) { + ret = qmc_chan_setup_tsa_tx(chan, false); + if (ret) { + dev_err(chan->qmc->dev, "chan %u: Disable tsa entries failed (%d)\n", + chan->id, ret); + goto end; + } + } + end: spin_unlock_irqrestore(>tx_lock, flags); return ret; } +static int qmc_chan_start_rx(struct qmc_chan *chan); + int qmc_chan_stop(struct qmc_chan *chan, int direction) { - int ret; + bool is_rx_rollback_needed = false; + unsigned long flags; +
[PATCH v2 14/17] soc: fsl: cpm1: qmc: Introduce is_tsa_64rxtx flag
In order to support runtime timeslot route changes, some operations will be different according the routing table used (common Rx and Tx table or one table for Rx and one for Tx). The is_tsa_64rxtx flag is introduced to avoid extra computation to determine the table format each time we need it. It is set once at initialization. Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index 5ca4120779f8..e651b3bba1ca 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -216,6 +216,7 @@ struct qmc { u16 __iomem *int_curr; dma_addr_t int_dma_addr; size_t int_size; + bool is_tsa_64rxtx; struct list_head chan_head; struct qmc_chan *chans[64]; }; @@ -696,7 +697,7 @@ static int qmc_chan_setup_tsa(struct qmc_chan *chan, bool enable) * Setup one common 64 entries table or two 32 entries (one for Tx * and one for Tx) according to assigned TS numbers. */ - if (info.nb_tx_ts > 32 || info.nb_rx_ts > 32) + if (chan->qmc->is_tsa_64rxtx) return qmc_chan_setup_tsa_64rxtx(chan, , enable); ret = qmc_chan_setup_tsa_32rx(chan, , enable); @@ -1053,6 +1054,7 @@ static int qmc_init_tsa_64rxtx(struct qmc *qmc, const struct tsa_serial_info *in * Everything was previously checked, Tx and Rx related stuffs are * identical -> Used Rx related stuff to build the table */ + qmc->is_tsa_64rxtx = true; /* Invalidate all entries */ for (i = 0; i < 64; i++) @@ -1081,6 +1083,7 @@ static int qmc_init_tsa_32rx_32tx(struct qmc *qmc, const struct tsa_serial_info * Use a Tx 32 entries table and a Rx 32 entries table. * Everything was previously checked. */ + qmc->is_tsa_64rxtx = false; /* Invalidate all entries */ for (i = 0; i < 32; i++) { -- 2.43.0
[PATCH v2 13/17] soc: fsl: cpm1: qmc: Split Tx and Rx TSA entries setup
The Tx and Rx entries for a given channel are set in one function. In order to modify Rx entries and Tx entries independently of one other, split this function in one for the Rx part and one for the Tx part. Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 49 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index c1318fad296b..5ca4120779f8 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -610,14 +610,14 @@ static int qmc_chan_setup_tsa_64rxtx(struct qmc_chan *chan, const struct tsa_ser return 0; } -static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct tsa_serial_info *info, - bool enable) +static int qmc_chan_setup_tsa_32rx(struct qmc_chan *chan, const struct tsa_serial_info *info, + bool enable) { unsigned int i; u16 curr; u16 val; - /* Use a Tx 32 entries table and a Rx 32 entries table */ + /* Use a Rx 32 entries table */ val = QMC_TSA_VALID | QMC_TSA_MASK | QMC_TSA_CHANNEL(chan->id); @@ -633,6 +633,30 @@ static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct tsa_ return -EBUSY; } } + + /* Set entries based on Rx stuff */ + for (i = 0; i < info->nb_rx_ts; i++) { + if (!(chan->rx_ts_mask & (((u64)1) << i))) + continue; + + qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), +~QMC_TSA_WRAP, enable ? val : 0x); + } + + return 0; +} + +static int qmc_chan_setup_tsa_32tx(struct qmc_chan *chan, const struct tsa_serial_info *info, + bool enable) +{ + unsigned int i; + u16 curr; + u16 val; + + /* Use a Tx 32 entries table */ + + val = QMC_TSA_VALID | QMC_TSA_MASK | QMC_TSA_CHANNEL(chan->id); + /* Check entries based on Tx stuff */ for (i = 0; i < info->nb_tx_ts; i++) { if (!(chan->tx_ts_mask & (((u64)1) << i))) @@ -646,14 +670,6 @@ static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct tsa_ } } - /* Set entries based on Rx stuff */ - for (i = 0; i < info->nb_rx_ts; i++) { - if (!(chan->rx_ts_mask & (((u64)1) << i))) - continue; - - qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), -~QMC_TSA_WRAP, enable ? val : 0x); - } /* Set entries based on Tx stuff */ for (i = 0; i < info->nb_tx_ts; i++) { if (!(chan->tx_ts_mask & (((u64)1) << i))) @@ -680,9 +696,14 @@ static int qmc_chan_setup_tsa(struct qmc_chan *chan, bool enable) * Setup one common 64 entries table or two 32 entries (one for Tx * and one for Tx) according to assigned TS numbers. */ - return ((info.nb_tx_ts > 32) || (info.nb_rx_ts > 32)) ? - qmc_chan_setup_tsa_64rxtx(chan, , enable) : - qmc_chan_setup_tsa_32rx_32tx(chan, , enable); + if (info.nb_tx_ts > 32 || info.nb_rx_ts > 32) + return qmc_chan_setup_tsa_64rxtx(chan, , enable); + + ret = qmc_chan_setup_tsa_32rx(chan, , enable); + if (ret) + return ret; + + return qmc_chan_setup_tsa_32tx(chan, , enable); } static int qmc_chan_command(struct qmc_chan *chan, u8 qmc_opcode) -- 2.43.0
[PATCH v2 12/17] soc: fsl: cpm1: qmc: Add support for disabling channel TSA entries
In order to allow runtime timeslot route changes, disabling channel TSA entries needs to be supported. Add support for this new feature. Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 20 +++- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index 8d71e63d0f21..c1318fad296b 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -567,7 +567,8 @@ static void qmc_chan_read_done(struct qmc_chan *chan) spin_unlock_irqrestore(>rx_lock, flags); } -static int qmc_chan_setup_tsa_64rxtx(struct qmc_chan *chan, const struct tsa_serial_info *info) +static int qmc_chan_setup_tsa_64rxtx(struct qmc_chan *chan, const struct tsa_serial_info *info, +bool enable) { unsigned int i; u16 curr; @@ -603,13 +604,14 @@ static int qmc_chan_setup_tsa_64rxtx(struct qmc_chan *chan, const struct tsa_ser continue; qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), -~QMC_TSA_WRAP, val); +~QMC_TSA_WRAP, enable ? val : 0x); } return 0; } -static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct tsa_serial_info *info) +static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct tsa_serial_info *info, + bool enable) { unsigned int i; u16 curr; @@ -650,7 +652,7 @@ static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct tsa_ continue; qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), -~QMC_TSA_WRAP, val); +~QMC_TSA_WRAP, enable ? val : 0x); } /* Set entries based on Tx stuff */ for (i = 0; i < info->nb_tx_ts; i++) { @@ -658,13 +660,13 @@ static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct tsa_ continue; qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATTX + (i * 2), -~QMC_TSA_WRAP, val); +~QMC_TSA_WRAP, enable ? val : 0x); } return 0; } -static int qmc_chan_setup_tsa(struct qmc_chan *chan) +static int qmc_chan_setup_tsa(struct qmc_chan *chan, bool enable) { struct tsa_serial_info info; int ret; @@ -679,8 +681,8 @@ static int qmc_chan_setup_tsa(struct qmc_chan *chan) * and one for Tx) according to assigned TS numbers. */ return ((info.nb_tx_ts > 32) || (info.nb_rx_ts > 32)) ? - qmc_chan_setup_tsa_64rxtx(chan, ) : - qmc_chan_setup_tsa_32rx_32tx(chan, ); + qmc_chan_setup_tsa_64rxtx(chan, , enable) : + qmc_chan_setup_tsa_32rx_32tx(chan, , enable); } static int qmc_chan_command(struct qmc_chan *chan, u8 qmc_opcode) @@ -1146,7 +1148,7 @@ static int qmc_setup_chan(struct qmc *qmc, struct qmc_chan *chan) chan->qmc = qmc; - ret = qmc_chan_setup_tsa(chan); + ret = qmc_chan_setup_tsa(chan, true); if (ret) return ret; -- 2.43.0
[PATCH v2 11/17] soc: fsl: cpm1: qmc: Check available timeslots in qmc_check_chans()
The timeslots checked in qmc_check_chans() are the timeslots used. With the introduction of the available timeslots, the used timeslots are a subset of the available timeslots. The timeslots checked during the qmc_check_chans() call should be the available ones. Simply update and check the available timeslots instead of the used timeslots in qmc_check_chans(). Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index f2a71a140db7..8d71e63d0f21 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -914,13 +914,13 @@ static int qmc_check_chans(struct qmc *qmc) rx_ts_assigned_mask = info.nb_rx_ts == 64 ? U64_MAX : (((u64)1) << info.nb_rx_ts) - 1; list_for_each_entry(chan, >chan_head, list) { - if (chan->tx_ts_mask > tx_ts_assigned_mask) { - dev_err(qmc->dev, "chan %u uses TSA unassigned Tx TS\n", chan->id); + if (chan->tx_ts_mask_avail > tx_ts_assigned_mask) { + dev_err(qmc->dev, "chan %u can use TSA unassigned Tx TS\n", chan->id); return -EINVAL; } - if (chan->rx_ts_mask > rx_ts_assigned_mask) { - dev_err(qmc->dev, "chan %u uses TSA unassigned Rx TS\n", chan->id); + if (chan->rx_ts_mask_avail > rx_ts_assigned_mask) { + dev_err(qmc->dev, "chan %u can use TSA unassigned Rx TS\n", chan->id); return -EINVAL; } } -- 2.43.0
[PATCH v2 10/17] soc: fsl: cpm1: qmc: Remove no more needed checks from qmc_check_chans()
The newly introduced qmc_chan_setup_tsa* functions check that the channel entries are not already used. These checks are also performed by qmc_check_chans() and are no more needed. Remove them from qmc_check_chans(). Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 20 1 file changed, 20 deletions(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index 5d7e2ecdd933..f2a71a140db7 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -884,10 +884,7 @@ EXPORT_SYMBOL(qmc_chan_reset); static int qmc_check_chans(struct qmc *qmc) { struct tsa_serial_info info; - bool is_one_table = false; struct qmc_chan *chan; - u64 tx_ts_mask = 0; - u64 rx_ts_mask = 0; u64 tx_ts_assigned_mask; u64 rx_ts_assigned_mask; int ret; @@ -911,7 +908,6 @@ static int qmc_check_chans(struct qmc *qmc) dev_err(qmc->dev, "Number of TSA Tx/Rx TS assigned are not equal\n"); return -EINVAL; } - is_one_table = true; } tx_ts_assigned_mask = info.nb_tx_ts == 64 ? U64_MAX : (((u64)1) << info.nb_tx_ts) - 1; @@ -922,27 +918,11 @@ static int qmc_check_chans(struct qmc *qmc) dev_err(qmc->dev, "chan %u uses TSA unassigned Tx TS\n", chan->id); return -EINVAL; } - if (tx_ts_mask & chan->tx_ts_mask) { - dev_err(qmc->dev, "chan %u uses an already used Tx TS\n", chan->id); - return -EINVAL; - } if (chan->rx_ts_mask > rx_ts_assigned_mask) { dev_err(qmc->dev, "chan %u uses TSA unassigned Rx TS\n", chan->id); return -EINVAL; } - if (rx_ts_mask & chan->rx_ts_mask) { - dev_err(qmc->dev, "chan %u uses an already used Rx TS\n", chan->id); - return -EINVAL; - } - - if (is_one_table && (chan->tx_ts_mask != chan->rx_ts_mask)) { - dev_err(qmc->dev, "chan %u uses different Rx and Tx TS\n", chan->id); - return -EINVAL; - } - - tx_ts_mask |= chan->tx_ts_mask; - rx_ts_mask |= chan->rx_ts_mask; } return 0; -- 2.43.0
[PATCH v2 09/17] soc: fsl: cpm1: qmc: Introduce qmc_chan_setup_tsa*
Introduce the qmc_chan_setup_tsa* functions to setup entries related to the given channel. Use them during QMC channels setup. Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 161 ++- 1 file changed, 125 insertions(+), 36 deletions(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index e3f2afb8fa4d..5d7e2ecdd933 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -240,6 +240,11 @@ static void qmc_clrbits16(void __iomem *addr, u16 clr) qmc_write16(addr, qmc_read16(addr) & ~clr); } +static void qmc_clrsetbits16(void __iomem *addr, u16 clr, u16 set) +{ + qmc_write16(addr, (qmc_read16(addr) & ~clr) | set); +} + static void qmc_write32(void __iomem *addr, u32 val) { iowrite32be(val, addr); @@ -562,6 +567,122 @@ static void qmc_chan_read_done(struct qmc_chan *chan) spin_unlock_irqrestore(>rx_lock, flags); } +static int qmc_chan_setup_tsa_64rxtx(struct qmc_chan *chan, const struct tsa_serial_info *info) +{ + unsigned int i; + u16 curr; + u16 val; + + /* +* Use a common Tx/Rx 64 entries table. +* Tx and Rx related stuffs must be identical +*/ + if (chan->tx_ts_mask != chan->rx_ts_mask) { + dev_err(chan->qmc->dev, "chan %u uses different Rx and Tx TS\n", chan->id); + return -EINVAL; + } + + val = QMC_TSA_VALID | QMC_TSA_MASK | QMC_TSA_CHANNEL(chan->id); + + /* Check entries based on Rx stuff*/ + for (i = 0; i < info->nb_rx_ts; i++) { + if (!(chan->rx_ts_mask & (((u64)1) << i))) + continue; + + curr = qmc_read16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2)); + if (curr & QMC_TSA_VALID && (curr & ~QMC_TSA_WRAP) != val) { + dev_err(chan->qmc->dev, "chan %u TxRx entry %d already used\n", + chan->id, i); + return -EBUSY; + } + } + + /* Set entries based on Rx stuff*/ + for (i = 0; i < info->nb_rx_ts; i++) { + if (!(chan->rx_ts_mask & (((u64)1) << i))) + continue; + + qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), +~QMC_TSA_WRAP, val); + } + + return 0; +} + +static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct tsa_serial_info *info) +{ + unsigned int i; + u16 curr; + u16 val; + + /* Use a Tx 32 entries table and a Rx 32 entries table */ + + val = QMC_TSA_VALID | QMC_TSA_MASK | QMC_TSA_CHANNEL(chan->id); + + /* Check entries based on Rx stuff */ + for (i = 0; i < info->nb_rx_ts; i++) { + if (!(chan->rx_ts_mask & (((u64)1) << i))) + continue; + + curr = qmc_read16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2)); + if (curr & QMC_TSA_VALID && (curr & ~QMC_TSA_WRAP) != val) { + dev_err(chan->qmc->dev, "chan %u Rx entry %d already used\n", + chan->id, i); + return -EBUSY; + } + } + /* Check entries based on Tx stuff */ + for (i = 0; i < info->nb_tx_ts; i++) { + if (!(chan->tx_ts_mask & (((u64)1) << i))) + continue; + + curr = qmc_read16(chan->qmc->scc_pram + QMC_GBL_TSATTX + (i * 2)); + if (curr & QMC_TSA_VALID && (curr & ~QMC_TSA_WRAP) != val) { + dev_err(chan->qmc->dev, "chan %u Tx entry %d already used\n", + chan->id, i); + return -EBUSY; + } + } + + /* Set entries based on Rx stuff */ + for (i = 0; i < info->nb_rx_ts; i++) { + if (!(chan->rx_ts_mask & (((u64)1) << i))) + continue; + + qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2), +~QMC_TSA_WRAP, val); + } + /* Set entries based on Tx stuff */ + for (i = 0; i < info->nb_tx_ts; i++) { + if (!(chan->tx_ts_mask & (((u64)1) << i))) + continue; + + qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATTX + (i * 2), +~QMC_TSA_WRAP, val); + } + + return 0; +} + +static int qmc_chan_setup_tsa(struct qmc_chan *chan) +{ + struct tsa_serial_info info; + int ret; + + /* Retrieve info from the TSA related serial */ + ret = tsa_serial_get_info(chan->qmc->tsa_serial, ); + if (ret) + return ret; + + /* +* Setup one common 64 entries table or two 32 entries (one for Tx +* and one for Tx) according to assigned TS numbers. +*/ + return ((info.nb_tx_ts > 32) ||
[PATCH v2 08/17] soc: fsl: cpm1: qmc: Rename qmc_setup_tsa* to qmc_init_tsa*
qmc_setup_tsa* are called once at initialisation. They initialize the QMC TSA table. In order to introduce setup function later on for dynamic timeslots management, rename the function to avoid later confusion. Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index 0413e25d4c67..e3f2afb8fa4d 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -919,7 +919,7 @@ static int qmc_of_parse_chans(struct qmc *qmc, struct device_node *np) return qmc_check_chans(qmc); } -static int qmc_setup_tsa_64rxtx(struct qmc *qmc, const struct tsa_serial_info *info) +static int qmc_init_tsa_64rxtx(struct qmc *qmc, const struct tsa_serial_info *info) { struct qmc_chan *chan; unsigned int i; @@ -961,7 +961,7 @@ static int qmc_setup_tsa_64rxtx(struct qmc *qmc, const struct tsa_serial_info *i return 0; } -static int qmc_setup_tsa_32rx_32tx(struct qmc *qmc, const struct tsa_serial_info *info) +static int qmc_init_tsa_32rx_32tx(struct qmc *qmc, const struct tsa_serial_info *info) { struct qmc_chan *chan; unsigned int i; @@ -1019,7 +1019,7 @@ static int qmc_setup_tsa_32rx_32tx(struct qmc *qmc, const struct tsa_serial_info return 0; } -static int qmc_setup_tsa(struct qmc *qmc) +static int qmc_init_tsa(struct qmc *qmc) { struct tsa_serial_info info; int ret; @@ -1030,12 +1030,12 @@ static int qmc_setup_tsa(struct qmc *qmc) return ret; /* -* Setup one common 64 entries table or two 32 entries (one for Tx and -* one for Tx) according to assigned TS numbers. +* Initialize one common 64 entries table or two 32 entries (one for Tx +* and one for Tx) according to assigned TS numbers. */ return ((info.nb_tx_ts > 32) || (info.nb_rx_ts > 32)) ? - qmc_setup_tsa_64rxtx(qmc, ) : - qmc_setup_tsa_32rx_32tx(qmc, ); + qmc_init_tsa_64rxtx(qmc, ) : + qmc_init_tsa_32rx_32tx(qmc, ); } static int qmc_setup_chan_trnsync(struct qmc *qmc, struct qmc_chan *chan) @@ -1391,7 +1391,7 @@ static int qmc_probe(struct platform_device *pdev) qmc_write32(qmc->scc_pram + QMC_GBL_C_MASK32, 0xDEBB20E3); qmc_write16(qmc->scc_pram + QMC_GBL_C_MASK16, 0xF0B8); - ret = qmc_setup_tsa(qmc); + ret = qmc_init_tsa(qmc); if (ret) goto err_tsa_serial_disconnect; -- 2.43.0
[PATCH v2 01/17] soc: fsl: cpm1: tsa: Fix __iomem addresses declaration
Running sparse (make C=1) on tsa.c raises a lot of warning such as: --- 8< --- warning: incorrect type in assignment (different address spaces) expected void *[noderef] si_regs got void [noderef] __iomem * --- 8< --- Indeed, some variable were declared 'type *__iomem var' instead of 'type __iomem *var'. Use the correct declaration to remove these warnings. Fixes: 1d4ba0b81c1c ("soc: fsl: cpm1: Add support for TSA") Cc: sta...@vger.kernel.org Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202312051959.9ydriybg-...@intel.com/ Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/tsa.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/soc/fsl/qe/tsa.c b/drivers/soc/fsl/qe/tsa.c index 3f9981335590..6c5741cf5e9d 100644 --- a/drivers/soc/fsl/qe/tsa.c +++ b/drivers/soc/fsl/qe/tsa.c @@ -98,9 +98,9 @@ #define TSA_SIRP 0x10 struct tsa_entries_area { - void *__iomem entries_start; - void *__iomem entries_next; - void *__iomem last_entry; + void __iomem *entries_start; + void __iomem *entries_next; + void __iomem *last_entry; }; struct tsa_tdm { @@ -117,8 +117,8 @@ struct tsa_tdm { struct tsa { struct device *dev; - void *__iomem si_regs; - void *__iomem si_ram; + void __iomem *si_regs; + void __iomem *si_ram; resource_size_t si_ram_sz; spinlock_t lock; int tdms; /* TSA_TDMx ORed */ @@ -135,27 +135,27 @@ static inline struct tsa *tsa_serial_get_tsa(struct tsa_serial *tsa_serial) return container_of(tsa_serial, struct tsa, serials[tsa_serial->id]); } -static inline void tsa_write32(void *__iomem addr, u32 val) +static inline void tsa_write32(void __iomem *addr, u32 val) { iowrite32be(val, addr); } -static inline void tsa_write8(void *__iomem addr, u32 val) +static inline void tsa_write8(void __iomem *addr, u32 val) { iowrite8(val, addr); } -static inline u32 tsa_read32(void *__iomem addr) +static inline u32 tsa_read32(void __iomem *addr) { return ioread32be(addr); } -static inline void tsa_clrbits32(void *__iomem addr, u32 clr) +static inline void tsa_clrbits32(void __iomem *addr, u32 clr) { tsa_write32(addr, tsa_read32(addr) & ~clr); } -static inline void tsa_clrsetbits32(void *__iomem addr, u32 clr, u32 set) +static inline void tsa_clrsetbits32(void __iomem *addr, u32 clr, u32 set) { tsa_write32(addr, (tsa_read32(addr) & ~clr) | set); } @@ -313,7 +313,7 @@ static u32 tsa_serial_id2csel(struct tsa *tsa, u32 serial_id) static int tsa_add_entry(struct tsa *tsa, struct tsa_entries_area *area, u32 count, u32 serial_id) { - void *__iomem addr; + void __iomem *addr; u32 left; u32 val; u32 cnt; -- 2.43.0
[PATCH v2 00/17] Prepare the PowerQUICC QMC and TSA for the HDLC QMC driver
Hi, This series updates PowerQUICC QMC and TSA drivers to prepare the support for the QMC HDLC driver. Patches were previously sent as part of a full feature series: "Add support for QMC HDLC, framer infrastructure and PEF2256 framer" [1] The full feature series reached the v9 iteration. The v1 was sent the 07/25/2023 followed by the other iterations (07/26/2023, 08/09/2023, 08/18/2023, 09/12/2023, 09/22/2023, 09/28/2023, 10/11/23, 11/15/2023) and was ready to be merged in its v8. https://lore.kernel.org/linux-kernel/20231025123215.5caca...@kernel.org/ The lack of feedback from the Freescale SoC and the Quicc Engine maintainers (i.e. drivers/soc/fsl/qe/ to which the QMC and TSA drivers belong) blocks the entire full feature series. These patches are fixes and improvements to TSA and QMC drivers. These drivers were previously acked by Li Yang but without any feedback from Li Yang nor Qiang Zhao the series cannot move forward. In order to ease the review/merge, the full feature series has been split and this series contains patches related to the PowerQUICC SoC part (QMC and TSA). - Perform some fixes (patches 1 to 5) - Add support for child devices (patch 6) - Add QMC dynamic timeslot support (patches 7 to 17) Compare to the previous iteration: https://lore.kernel.org/linux-kernel/20231128140818.261541-1-herve.cod...@bootlin.com/ this v2 series: - Removes a forward declaration in the driver. - Adds kernel test robot tags as the issue was detected. - Adds some missing Cc: stable. Best regards, Hervé [1]: https://lore.kernel.org/linux-kernel/20231115144007.478111-1-herve.cod...@bootlin.com/ Changes v1 -> v2: - Patch 1 Add 'Reported-by: kernel test robot ' Add 'Closes: https://lore.kernel.org/oe-kbuild-all/202312051959.9ydriybg-...@intel.com/' Add 'Cc: sta...@vger.kernel.org' - Patch 2, 3 Add 'Cc: sta...@vger.kernel.org - Patch 15 Move qmc_setup_chan_trnsync() to avoid a forward declaration. Patches extracted: - Patch 1..6 : full feature series patch 1..6 - Patch 7..17 : full feature series patch 9..19 Herve Codina (17): soc: fsl: cpm1: tsa: Fix __iomem addresses declaration soc: fsl: cpm1: qmc: Fix __iomem addresses declaration soc: fsl: cpm1: qmc: Fix rx channel reset soc: fsl: cpm1: qmc: Extend the API to provide Rx status soc: fsl: cpm1: qmc: Remove inline function specifiers soc: fsl: cpm1: qmc: Add support for child devices soc: fsl: cpm1: qmc: Introduce available timeslots masks soc: fsl: cpm1: qmc: Rename qmc_setup_tsa* to qmc_init_tsa* soc: fsl: cpm1: qmc: Introduce qmc_chan_setup_tsa* soc: fsl: cpm1: qmc: Remove no more needed checks from qmc_check_chans() soc: fsl: cpm1: qmc: Check available timeslots in qmc_check_chans() soc: fsl: cpm1: qmc: Add support for disabling channel TSA entries soc: fsl: cpm1: qmc: Split Tx and Rx TSA entries setup soc: fsl: cpm1: qmc: Introduce is_tsa_64rxtx flag soc: fsl: cpm1: qmc: Handle timeslot entries at channel start() and stop() soc: fsl: cpm1: qmc: Remove timeslots handling from setup_chan() soc: fsl: cpm1: qmc: Introduce functions to change timeslots at runtime drivers/soc/fsl/qe/qmc.c | 658 ++ drivers/soc/fsl/qe/tsa.c | 22 +- include/soc/fsl/qe/qmc.h | 27 +- sound/soc/fsl/fsl_qmc_audio.c | 2 +- 4 files changed, 538 insertions(+), 171 deletions(-) -- 2.43.0
[PATCH v2 04/17] soc: fsl: cpm1: qmc: Extend the API to provide Rx status
In HDLC mode, some status flags related to the data read transfer can be set by the hardware and need to be known by a QMC consumer for further analysis. Extend the API in order to provide these transfer status flags at the read complete() call. In TRANSPARENT mode, these flags have no meaning. Keep only one read complete() API and update the consumers working in transparent mode. In this case, the newly introduced flags parameter is simply unused. Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 29 + include/soc/fsl/qe/qmc.h | 15 ++- sound/soc/fsl/fsl_qmc_audio.c | 2 +- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index 2312152a44b3..4b4832d93c9b 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -166,7 +166,7 @@ struct qmc_xfer_desc { union { void (*tx_complete)(void *context); - void (*rx_complete)(void *context, size_t length); + void (*rx_complete)(void *context, size_t length, unsigned int flags); }; void *context; }; @@ -421,7 +421,8 @@ static void qmc_chan_write_done(struct qmc_chan *chan) } int qmc_chan_read_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length, -void (*complete)(void *context, size_t length), void *context) +void (*complete)(void *context, size_t length, unsigned int flags), +void *context) { struct qmc_xfer_desc *xfer_desc; unsigned long flags; @@ -454,6 +455,10 @@ int qmc_chan_read_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length, xfer_desc->rx_complete = complete; xfer_desc->context = context; + /* Clear previous status flags */ + ctrl &= ~(QMC_BD_RX_L | QMC_BD_RX_F | QMC_BD_RX_LG | QMC_BD_RX_NO | + QMC_BD_RX_AB | QMC_BD_RX_CR); + /* Activate the descriptor */ ctrl |= (QMC_BD_RX_E | QMC_BD_RX_UB); wmb(); /* Be sure to flush data before descriptor activation */ @@ -485,7 +490,7 @@ EXPORT_SYMBOL(qmc_chan_read_submit); static void qmc_chan_read_done(struct qmc_chan *chan) { - void (*complete)(void *context, size_t size); + void (*complete)(void *context, size_t size, unsigned int flags); struct qmc_xfer_desc *xfer_desc; unsigned long flags; cbd_t __iomem *bd; @@ -527,7 +532,23 @@ static void qmc_chan_read_done(struct qmc_chan *chan) if (complete) { spin_unlock_irqrestore(>rx_lock, flags); - complete(context, datalen); + + /* +* Avoid conversion between internal hardware flags and +* the software API flags. +* -> Be sure that the software API flags are consistent +*with the hardware flags +*/ + BUILD_BUG_ON(QMC_RX_FLAG_HDLC_LAST != QMC_BD_RX_L); + BUILD_BUG_ON(QMC_RX_FLAG_HDLC_FIRST != QMC_BD_RX_F); + BUILD_BUG_ON(QMC_RX_FLAG_HDLC_OVF != QMC_BD_RX_LG); + BUILD_BUG_ON(QMC_RX_FLAG_HDLC_UNA != QMC_BD_RX_NO); + BUILD_BUG_ON(QMC_RX_FLAG_HDLC_ABORT != QMC_BD_RX_AB); + BUILD_BUG_ON(QMC_RX_FLAG_HDLC_CRC != QMC_BD_RX_CR); + + complete(context, datalen, +ctrl & (QMC_BD_RX_L | QMC_BD_RX_F | QMC_BD_RX_LG | +QMC_BD_RX_NO | QMC_BD_RX_AB | QMC_BD_RX_CR)); spin_lock_irqsave(>rx_lock, flags); } diff --git a/include/soc/fsl/qe/qmc.h b/include/soc/fsl/qe/qmc.h index 3c61a50d2ae2..6f1d6cebc9fe 100644 --- a/include/soc/fsl/qe/qmc.h +++ b/include/soc/fsl/qe/qmc.h @@ -9,6 +9,7 @@ #ifndef __SOC_FSL_QMC_H__ #define __SOC_FSL_QMC_H__ +#include #include struct device_node; @@ -56,8 +57,20 @@ int qmc_chan_set_param(struct qmc_chan *chan, const struct qmc_chan_param *param int qmc_chan_write_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length, void (*complete)(void *context), void *context); +/* Flags available (ORed) for read complete() flags parameter in HDLC mode. + * No flags are available in transparent mode and the read complete() flags + * parameter has no meaning in transparent mode. + */ +#define QMC_RX_FLAG_HDLC_LAST BIT(11) /* Last in frame */ +#define QMC_RX_FLAG_HDLC_FIRST BIT(10) /* First in frame */ +#define QMC_RX_FLAG_HDLC_OVF BIT(5) /* Data overflow */ +#define QMC_RX_FLAG_HDLC_UNA BIT(4) /* Unaligned (ie. bits received not multiple of 8) */ +#define QMC_RX_FLAG_HDLC_ABORT BIT(3) /* Received an abort sequence (seven consecutive ones) */ +#define QMC_RX_FLAG_HDLC_CRC BIT(2)
[PATCH v2 05/17] soc: fsl: cpm1: qmc: Remove inline function specifiers
The inline function specifier is present on some functions but it is better to let the compiler decide inlining or not these functions. Remove inline specifiers. Fixes: 3178d58e0b97 ("soc: fsl: cpm1: Add support for QMC") Signed-off-by: Herve Codina Suggested-by: Andrew Lunn Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index 4b4832d93c9b..27f2f16deac9 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -218,37 +218,37 @@ struct qmc { struct qmc_chan *chans[64]; }; -static inline void qmc_write16(void __iomem *addr, u16 val) +static void qmc_write16(void __iomem *addr, u16 val) { iowrite16be(val, addr); } -static inline u16 qmc_read16(void __iomem *addr) +static u16 qmc_read16(void __iomem *addr) { return ioread16be(addr); } -static inline void qmc_setbits16(void __iomem *addr, u16 set) +static void qmc_setbits16(void __iomem *addr, u16 set) { qmc_write16(addr, qmc_read16(addr) | set); } -static inline void qmc_clrbits16(void __iomem *addr, u16 clr) +static void qmc_clrbits16(void __iomem *addr, u16 clr) { qmc_write16(addr, qmc_read16(addr) & ~clr); } -static inline void qmc_write32(void __iomem *addr, u32 val) +static void qmc_write32(void __iomem *addr, u32 val) { iowrite32be(val, addr); } -static inline u32 qmc_read32(void __iomem *addr) +static u32 qmc_read32(void __iomem *addr) { return ioread32be(addr); } -static inline void qmc_setbits32(void __iomem *addr, u32 set) +static void qmc_setbits32(void __iomem *addr, u32 set) { qmc_write32(addr, qmc_read32(addr) | set); } -- 2.43.0
[PATCH v2 07/17] soc: fsl: cpm1: qmc: Introduce available timeslots masks
Available timeslots masks define timeslots available for the related channel. These timeslots are defined by the QMC binding. Timeslots used are initialized to available timeslots but can be a subset of available timeslots. This prepares the dynamic timeslots management (ie. changing timeslots at runtime). Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index e716f13669a0..0413e25d4c67 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -177,7 +177,9 @@ struct qmc_chan { struct qmc *qmc; void __iomem *s_param; enum qmc_mode mode; + u64 tx_ts_mask_avail; u64 tx_ts_mask; + u64 rx_ts_mask_avail; u64 rx_ts_mask; bool is_reverse_data; @@ -875,7 +877,8 @@ static int qmc_of_parse_chans(struct qmc *qmc, struct device_node *np) of_node_put(chan_np); return ret; } - chan->tx_ts_mask = ts_mask; + chan->tx_ts_mask_avail = ts_mask; + chan->tx_ts_mask = chan->tx_ts_mask_avail; ret = of_property_read_u64(chan_np, "fsl,rx-ts-mask", _mask); if (ret) { @@ -884,7 +887,8 @@ static int qmc_of_parse_chans(struct qmc *qmc, struct device_node *np) of_node_put(chan_np); return ret; } - chan->rx_ts_mask = ts_mask; + chan->rx_ts_mask_avail = ts_mask; + chan->rx_ts_mask = chan->rx_ts_mask_avail; mode = "transparent"; ret = of_property_read_string(chan_np, "fsl,operational-mode", ); -- 2.43.0
[PATCH v2 06/17] soc: fsl: cpm1: qmc: Add support for child devices
QMC child devices support is needed to avoid orphan DT nodes that use a simple DT phandle to reference a QMC channel. Allow to instantiate child devices and also extend the API to get the qmc_chan using a child device. Signed-off-by: Herve Codina --- drivers/soc/fsl/qe/qmc.c | 91 +++- include/soc/fsl/qe/qmc.h | 2 + 2 files changed, 73 insertions(+), 20 deletions(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index 27f2f16deac9..e716f13669a0 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -1425,8 +1425,16 @@ static int qmc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, qmc); + /* Populate channel related devices */ + ret = devm_of_platform_populate(qmc->dev); + if (ret) + goto err_disable_txrx; + return 0; +err_disable_txrx: + qmc_setbits32(qmc->scc_regs + SCC_GSMRL, 0); + err_disable_intr: qmc_write16(qmc->scc_regs + SCC_SCCM, 0); @@ -1465,26 +1473,16 @@ static struct platform_driver qmc_driver = { }; module_platform_driver(qmc_driver); -struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char *phandle_name) +static struct qmc_chan *qmc_chan_get_from_qmc(struct device_node *qmc_np, unsigned int chan_index) { - struct of_phandle_args out_args; struct platform_device *pdev; struct qmc_chan *qmc_chan; struct qmc *qmc; - int ret; - ret = of_parse_phandle_with_fixed_args(np, phandle_name, 1, 0, - _args); - if (ret < 0) - return ERR_PTR(ret); - - if (!of_match_node(qmc_driver.driver.of_match_table, out_args.np)) { - of_node_put(out_args.np); + if (!of_match_node(qmc_driver.driver.of_match_table, qmc_np)) return ERR_PTR(-EINVAL); - } - pdev = of_find_device_by_node(out_args.np); - of_node_put(out_args.np); + pdev = of_find_device_by_node(qmc_np); if (!pdev) return ERR_PTR(-ENODEV); @@ -1494,17 +1492,12 @@ struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char *phan return ERR_PTR(-EPROBE_DEFER); } - if (out_args.args_count != 1) { + if (chan_index >= ARRAY_SIZE(qmc->chans)) { platform_device_put(pdev); return ERR_PTR(-EINVAL); } - if (out_args.args[0] >= ARRAY_SIZE(qmc->chans)) { - platform_device_put(pdev); - return ERR_PTR(-EINVAL); - } - - qmc_chan = qmc->chans[out_args.args[0]]; + qmc_chan = qmc->chans[chan_index]; if (!qmc_chan) { platform_device_put(pdev); return ERR_PTR(-ENOENT); @@ -1512,8 +1505,44 @@ struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char *phan return qmc_chan; } + +struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char *phandle_name) +{ + struct of_phandle_args out_args; + struct qmc_chan *qmc_chan; + int ret; + + ret = of_parse_phandle_with_fixed_args(np, phandle_name, 1, 0, + _args); + if (ret < 0) + return ERR_PTR(ret); + + if (out_args.args_count != 1) { + of_node_put(out_args.np); + return ERR_PTR(-EINVAL); + } + + qmc_chan = qmc_chan_get_from_qmc(out_args.np, out_args.args[0]); + of_node_put(out_args.np); + return qmc_chan; +} EXPORT_SYMBOL(qmc_chan_get_byphandle); +struct qmc_chan *qmc_chan_get_bychild(struct device_node *np) +{ + struct device_node *qmc_np; + u32 chan_index; + int ret; + + qmc_np = np->parent; + ret = of_property_read_u32(np, "reg", _index); + if (ret) + return ERR_PTR(-EINVAL); + + return qmc_chan_get_from_qmc(qmc_np, chan_index); +} +EXPORT_SYMBOL(qmc_chan_get_bychild); + void qmc_chan_put(struct qmc_chan *chan) { put_device(chan->qmc->dev); @@ -1550,6 +1579,28 @@ struct qmc_chan *devm_qmc_chan_get_byphandle(struct device *dev, } EXPORT_SYMBOL(devm_qmc_chan_get_byphandle); +struct qmc_chan *devm_qmc_chan_get_bychild(struct device *dev, + struct device_node *np) +{ + struct qmc_chan *qmc_chan; + struct qmc_chan **dr; + + dr = devres_alloc(devm_qmc_chan_release, sizeof(*dr), GFP_KERNEL); + if (!dr) + return ERR_PTR(-ENOMEM); + + qmc_chan = qmc_chan_get_bychild(np); + if (!IS_ERR(qmc_chan)) { + *dr = qmc_chan; + devres_add(dev, dr); + } else { + devres_free(dr); + } + + return qmc_chan; +} +EXPORT_SYMBOL(devm_qmc_chan_get_bychild); + MODULE_AUTHOR("Herve Codina "); MODULE_DESCRIPTION("CPM QMC driver"); MODULE_LICENSE("GPL"); diff --git
[PATCH v2 02/17] soc: fsl: cpm1: qmc: Fix __iomem addresses declaration
Running sparse (make C=1) on qmc.c raises a lot of warning such as: ... warning: incorrect type in assignment (different address spaces) expected struct cpm_buf_desc [usertype] *[noderef] __iomem bd got struct cpm_buf_desc [noderef] [usertype] __iomem *txbd_free ... Indeed, some variable were declared 'type *__iomem var' instead of 'type __iomem *var'. Use the correct declaration to remove these warnings. Fixes: 3178d58e0b97 ("soc: fsl: cpm1: Add support for QMC") Cc: sta...@vger.kernel.org Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index 92ec76c03965..3f3de1351c96 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -175,7 +175,7 @@ struct qmc_chan { struct list_head list; unsigned int id; struct qmc *qmc; - void *__iomem s_param; + void __iomem *s_param; enum qmc_mode mode; u64 tx_ts_mask; u64 rx_ts_mask; @@ -203,9 +203,9 @@ struct qmc_chan { struct qmc { struct device *dev; struct tsa_serial *tsa_serial; - void *__iomem scc_regs; - void *__iomem scc_pram; - void *__iomem dpram; + void __iomem *scc_regs; + void __iomem *scc_pram; + void __iomem *dpram; u16 scc_pram_offset; cbd_t __iomem *bd_table; dma_addr_t bd_dma_addr; @@ -218,37 +218,37 @@ struct qmc { struct qmc_chan *chans[64]; }; -static inline void qmc_write16(void *__iomem addr, u16 val) +static inline void qmc_write16(void __iomem *addr, u16 val) { iowrite16be(val, addr); } -static inline u16 qmc_read16(void *__iomem addr) +static inline u16 qmc_read16(void __iomem *addr) { return ioread16be(addr); } -static inline void qmc_setbits16(void *__iomem addr, u16 set) +static inline void qmc_setbits16(void __iomem *addr, u16 set) { qmc_write16(addr, qmc_read16(addr) | set); } -static inline void qmc_clrbits16(void *__iomem addr, u16 clr) +static inline void qmc_clrbits16(void __iomem *addr, u16 clr) { qmc_write16(addr, qmc_read16(addr) & ~clr); } -static inline void qmc_write32(void *__iomem addr, u32 val) +static inline void qmc_write32(void __iomem *addr, u32 val) { iowrite32be(val, addr); } -static inline u32 qmc_read32(void *__iomem addr) +static inline u32 qmc_read32(void __iomem *addr) { return ioread32be(addr); } -static inline void qmc_setbits32(void *__iomem addr, u32 set) +static inline void qmc_setbits32(void __iomem *addr, u32 set) { qmc_write32(addr, qmc_read32(addr) | set); } @@ -318,7 +318,7 @@ int qmc_chan_write_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length, { struct qmc_xfer_desc *xfer_desc; unsigned long flags; - cbd_t *__iomem bd; + cbd_t __iomem *bd; u16 ctrl; int ret; @@ -374,7 +374,7 @@ static void qmc_chan_write_done(struct qmc_chan *chan) void (*complete)(void *context); unsigned long flags; void *context; - cbd_t *__iomem bd; + cbd_t __iomem *bd; u16 ctrl; /* @@ -425,7 +425,7 @@ int qmc_chan_read_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length, { struct qmc_xfer_desc *xfer_desc; unsigned long flags; - cbd_t *__iomem bd; + cbd_t __iomem *bd; u16 ctrl; int ret; @@ -488,7 +488,7 @@ static void qmc_chan_read_done(struct qmc_chan *chan) void (*complete)(void *context, size_t size); struct qmc_xfer_desc *xfer_desc; unsigned long flags; - cbd_t *__iomem bd; + cbd_t __iomem *bd; void *context; u16 datalen; u16 ctrl; @@ -663,7 +663,7 @@ static void qmc_chan_reset_rx(struct qmc_chan *chan) { struct qmc_xfer_desc *xfer_desc; unsigned long flags; - cbd_t *__iomem bd; + cbd_t __iomem *bd; u16 ctrl; spin_lock_irqsave(>rx_lock, flags); @@ -694,7 +694,7 @@ static void qmc_chan_reset_tx(struct qmc_chan *chan) { struct qmc_xfer_desc *xfer_desc; unsigned long flags; - cbd_t *__iomem bd; + cbd_t __iomem *bd; u16 ctrl; spin_lock_irqsave(>tx_lock, flags); -- 2.43.0
[PATCH v2 03/17] soc: fsl: cpm1: qmc: Fix rx channel reset
The qmc_chan_reset_rx() set the is_rx_stopped flag. This leads to an inconsistent state in the following sequence. qmc_chan_stop() qmc_chan_reset() Indeed, after the qmc_chan_reset() call, the channel must still be stopped. Only a qmc_chan_start() call can move the channel from stopped state to started state. Fix the issue removing the is_rx_stopped flag setting from qmc_chan_reset() Fixes: 3178d58e0b97 ("soc: fsl: cpm1: Add support for QMC") Cc: sta...@vger.kernel.org Signed-off-by: Herve Codina Reviewed-by: Christophe Leroy --- drivers/soc/fsl/qe/qmc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c index 3f3de1351c96..2312152a44b3 100644 --- a/drivers/soc/fsl/qe/qmc.c +++ b/drivers/soc/fsl/qe/qmc.c @@ -685,7 +685,6 @@ static void qmc_chan_reset_rx(struct qmc_chan *chan) qmc_read16(chan->s_param + QMC_SPE_RBASE)); chan->rx_pending = 0; - chan->is_rx_stopped = false; spin_unlock_irqrestore(>rx_lock, flags); } -- 2.43.0
Re: [PATCH v13 5/6] powerpc: add crash CPU hotplug support
Hi Sourabh, kernel test robot noticed the following build errors: [auto build test ERROR on powerpc/next] [also build test ERROR on powerpc/fixes tip/x86/core akpm-mm/mm-everything linus/master v6.7-rc4 next-20231205] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Sourabh-Jain/crash-make-CPU-and-Memory-hotplug-support-reporting-flexible/20231204-143305 base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next patch link: https://lore.kernel.org/r/20231204053253.25305-6-sourabhjain%40linux.ibm.com patch subject: [PATCH v13 5/6] powerpc: add crash CPU hotplug support config: powerpc64-randconfig-001-20231205 (https://download.01.org/0day-ci/archive/20231205/202312052234.oinhx3bt-...@intel.com/config) compiler: powerpc64-linux-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231205/202312052234.oinhx3bt-...@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202312052234.oinhx3bt-...@intel.com/ All errors (new ones prefixed by >>): arch/powerpc/kexec/file_load_64.c: In function 'kexec_extra_fdt_size_ppc64': >> arch/powerpc/kexec/file_load_64.c:953:52: error: 'threads_per_core' >> undeclared (first use in this function) 953 | possible_cpu_nodes = num_possible_cpus() / threads_per_core; |^~~~ arch/powerpc/kexec/file_load_64.c:953:52: note: each undeclared identifier is reported only once for each function it appears in vim +/threads_per_core +953 arch/powerpc/kexec/file_load_64.c 915 916 // Budget some space for the password blob. There's already extra space 917 // for the key name 918 if (plpks_is_available()) 919 extra_size += (unsigned int)plpks_get_passwordlen(); 920 921 if (image->type != KEXEC_TYPE_CRASH) 922 return extra_size; 923 924 /* 925 * For kdump kernel, account for linux,usable-memory and 926 * linux,drconf-usable-memory properties. Get an approximate on the 927 * number of usable memory entries and use for FDT size estimation. 928 */ 929 if (drmem_lmb_size()) { 930 usm_entries = ((memory_hotplug_max() / drmem_lmb_size()) + 931 (2 * (resource_size(_res) / drmem_lmb_size(; 932 extra_size += (unsigned int)(usm_entries * sizeof(u64)); 933 } 934 935 /* 936 * Get the number of CPU nodes in the current DT. This allows to 937 * reserve places for CPU nodes added since the boot time. 938 */ 939 cpu_nodes = 0; 940 for_each_node_by_type(dn, "cpu") { 941 cpu_nodes++; 942 } 943 944 if (cpu_nodes > boot_cpu_node_count) 945 extra_size += (cpu_nodes - boot_cpu_node_count) * cpu_node_size(); 946 947 #ifdef CONFIG_CRASH_HOTPLUG 948 /* 949 * Make sure enough space is reserved to accommodate possible CPU nodes 950 * in the crash FDT. This allows packing possible CPU nodes which are 951 * not yet present in the system without regenerating the entire FDT. 952 */ > 953 possible_cpu_nodes = num_possible_cpus() / threads_per_core; 954 if (image->type == KEXEC_TYPE_CRASH && possible_cpu_nodes > cpu_nodes) 955 extra_size += (possible_cpu_nodes - cpu_nodes) * cpu_node_size(); 956 #endif 957 958 return extra_size; 959 } 960 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
[PATCH] serial: ucc_uart: Fix multiple address space type errors
sparse reports multiple problems with address space type. Most problems are linked to missing __iomem qualifier. Others are caused by dereferencing __iomem addresses. Fix all this by adding missing __iomem and using ioread32be(). Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202312050412.zn2pkars-...@intel.com/ Signed-off-by: Christophe Leroy --- drivers/tty/serial/ucc_uart.c | 28 ++-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index ed7a6bb5596a..25903d492023 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -189,10 +189,10 @@ struct uart_qe_port { u16 tx_fifosize; int wait_closing; u32 flags; - struct qe_bd *rx_bd_base; - struct qe_bd *rx_cur; - struct qe_bd *tx_bd_base; - struct qe_bd *tx_cur; + struct qe_bd __iomem *rx_bd_base; + struct qe_bd __iomem *rx_cur; + struct qe_bd __iomem *tx_bd_base; + struct qe_bd __iomem *tx_cur; unsigned char *tx_buf; unsigned char *rx_buf; void *bd_virt; /* virtual address of the BD buffers */ @@ -258,7 +258,7 @@ static unsigned int qe_uart_tx_empty(struct uart_port *port) { struct uart_qe_port *qe_port = container_of(port, struct uart_qe_port, port); - struct qe_bd *bdp = qe_port->tx_bd_base; + struct qe_bd __iomem *bdp = qe_port->tx_bd_base; while (1) { if (ioread16be(>status) & BD_SC_READY) @@ -330,7 +330,7 @@ static void qe_uart_stop_tx(struct uart_port *port) */ static int qe_uart_tx_pump(struct uart_qe_port *qe_port) { - struct qe_bd *bdp; + struct qe_bd __iomem *bdp; unsigned char *p; unsigned int count; struct uart_port *port = _port->port; @@ -341,7 +341,7 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port) /* Pick next descriptor and fill from buffer */ bdp = qe_port->tx_cur; - p = qe2cpu_addr(be32_to_cpu(bdp->buf), qe_port); + p = qe2cpu_addr(ioread32be(>buf), qe_port); *p++ = port->x_char; iowrite16be(1, >length); @@ -368,7 +368,7 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port) while (!(ioread16be(>status) & BD_SC_READY) && !uart_circ_empty(xmit)) { count = 0; - p = qe2cpu_addr(be32_to_cpu(bdp->buf), qe_port); + p = qe2cpu_addr(ioread32be(>buf), qe_port); while (count < qe_port->tx_fifosize) { *p++ = xmit->buf[xmit->tail]; uart_xmit_advance(port, 1); @@ -460,7 +460,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port) unsigned char ch, *cp; struct uart_port *port = _port->port; struct tty_port *tport = >state->port; - struct qe_bd *bdp; + struct qe_bd __iomem *bdp; u16 status; unsigned int flg; @@ -487,7 +487,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port) } /* get pointer */ - cp = qe2cpu_addr(be32_to_cpu(bdp->buf), qe_port); + cp = qe2cpu_addr(ioread32be(>buf), qe_port); /* loop through the buffer */ while (i-- > 0) { @@ -590,7 +590,7 @@ static void qe_uart_initbd(struct uart_qe_port *qe_port) { int i; void *bd_virt; - struct qe_bd *bdp; + struct qe_bd __iomem *bdp; /* Set the physical address of the host memory buffers in the buffer * descriptors, and the virtual address for us to work with. @@ -648,7 +648,7 @@ static void qe_uart_init_ucc(struct uart_qe_port *qe_port) { u32 cecr_subblock; struct ucc_slow __iomem *uccp = qe_port->uccp; - struct ucc_uart_pram *uccup = qe_port->uccup; + struct ucc_uart_pram __iomem *uccup = qe_port->uccup; unsigned int i; @@ -983,7 +983,7 @@ static int qe_uart_request_port(struct uart_port *port) qe_port->us_private = uccs; qe_port->uccp = uccs->us_regs; - qe_port->uccup = (struct ucc_uart_pram *) uccs->us_pram; + qe_port->uccup = (struct ucc_uart_pram __iomem *)uccs->us_pram; qe_port->rx_bd_base = uccs->rx_bd; qe_port->tx_bd_base = uccs->tx_bd; @@ -1156,7 +1156,7 @@ static void uart_firmware_cont(const struct firmware *fw, void *context) firmware = (struct qe_firmware *) fw->data; - if (firmware->header.length != fw->size) { + if (be32_to_cpu(firmware->header.length) != fw->size) { dev_err(dev, "invalid firmware\n"); goto out; } -- 2.41.0
Re: [PATCH] powerpc/irq: Allow softirq to hardirq stack transition
Le 30/11/2023 à 13:50, Michael Ellerman a écrit : > Allow a transition from the softirq stack to the hardirq stack when > handling a hardirq. Doing so means a hardirq received while deep in > softirq processing is less likely to cause a stack overflow of the > softirq stack. > > Previously it wasn't safe to do so because irq_exit() (which initiates > softirq processing) was called on the hardirq stack. > > That was changed in commit 1b1b6a6f4cc0 ("powerpc: handle irq_enter/ > irq_exit in interrupt handler wrappers") and 1346d00e1bdf ("powerpc: > Don't select HAVE_IRQ_EXIT_ON_IRQ_STACK"). > > The allowed transitions are now: > - process stack -> hardirq stack > - process stack -> softirq stack > - process stack -> softirq stack -> hardirq stack > > Signed-off-by: Michael Ellerman Reviewed-by: Christophe Leroy > --- > arch/powerpc/kernel/irq.c | 5 ++--- > 1 file changed, 2 insertions(+), 3 deletions(-) > > diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c > index 6f7d4edaa0bc..7504ceec5c58 100644 > --- a/arch/powerpc/kernel/irq.c > +++ b/arch/powerpc/kernel/irq.c > @@ -284,15 +284,14 @@ static __always_inline void call_do_irq(struct pt_regs > *regs, void *sp) > void __do_IRQ(struct pt_regs *regs) > { > struct pt_regs *old_regs = set_irq_regs(regs); > - void *cursp, *irqsp, *sirqsp; > + void *cursp, *irqsp; > > /* Switch to the irq stack to handle this */ > cursp = (void *)(current_stack_pointer & ~(THREAD_SIZE - 1)); > irqsp = hardirq_ctx[raw_smp_processor_id()]; > - sirqsp = softirq_ctx[raw_smp_processor_id()]; > > /* Already there ? If not switch stack and call */ > - if (unlikely(cursp == irqsp || cursp == sirqsp)) > + if (unlikely(cursp == irqsp)) > __do_irq(regs, current_stack_pointer); > else > call_do_irq(regs, irqsp);
Re: [PATCH v2 2/2] powerpc/book3s64: Avoid __pte_protnone() check in __pte_flags_need_flush()
Le 04/12/2023 à 10:36, aneesh.ku...@kernel.org a écrit : > From: "Aneesh Kumar K.V (IBM)" > > This reverts commit 1abce0580b89 ("powerpc/64s: Fix __pte_needs_flush() > false positive warning") > > The previous patch dropped the usage of _PAGE_PRIVILEGED with PAGE_NONE. > Hence this check can be dropped. > > Signed-off-by: Aneesh Kumar K.V (IBM) Reviewed-by: Christophe Leroy > --- > arch/powerpc/include/asm/book3s/64/tlbflush.h | 9 ++--- > 1 file changed, 2 insertions(+), 7 deletions(-) > > diff --git a/arch/powerpc/include/asm/book3s/64/tlbflush.h > b/arch/powerpc/include/asm/book3s/64/tlbflush.h > index 1950c1b825b4..fd642b729775 100644 > --- a/arch/powerpc/include/asm/book3s/64/tlbflush.h > +++ b/arch/powerpc/include/asm/book3s/64/tlbflush.h > @@ -158,11 +158,6 @@ static inline void flush_tlb_fix_spurious_fault(struct > vm_area_struct *vma, >*/ > } > > -static inline bool __pte_protnone(unsigned long pte) > -{ > - return (pte & (pgprot_val(PAGE_NONE) | _PAGE_RWX)) == > pgprot_val(PAGE_NONE); > -} > - > static inline bool __pte_flags_need_flush(unsigned long oldval, > unsigned long newval) > { > @@ -179,8 +174,8 @@ static inline bool __pte_flags_need_flush(unsigned long > oldval, > /* >* We do not expect kernel mappings or non-PTEs or not-present PTEs. >*/ > - VM_WARN_ON_ONCE(!__pte_protnone(oldval) && oldval & _PAGE_PRIVILEGED); > - VM_WARN_ON_ONCE(!__pte_protnone(newval) && newval & _PAGE_PRIVILEGED); > + VM_WARN_ON_ONCE(oldval & _PAGE_PRIVILEGED); > + VM_WARN_ON_ONCE(newval & _PAGE_PRIVILEGED); > VM_WARN_ON_ONCE(!(oldval & _PAGE_PTE)); > VM_WARN_ON_ONCE(!(newval & _PAGE_PTE)); > VM_WARN_ON_ONCE(!(oldval & _PAGE_PRESENT));
Re: [PATCH v2 1/2] powerpc/book3s/hash: Drop _PAGE_PRIVILEGED from PAGE_NONE
Le 04/12/2023 à 10:36, aneesh.ku...@kernel.org a écrit : > From: "Aneesh Kumar K.V (IBM)" > > There used to be a dependency on _PAGE_PRIVILEGED with pte_savedwrite. > But that got dropped by > commit 6a56ccbcf6c6 ("mm/autonuma: use can_change_(pte|pmd)_writable() to > replace savedwrite") > > With the change in this patch numa fault pte (pte_protnone()) gets mapped as > regular user pte > with RWX cleared (no-access) whereas earlier it used to be mapped > _PAGE_PRIVILEGED. > > Hash fault handling code gets some WARN_ON added in this patch because > those functions are not expected to get called with _PAGE_READ cleared. > commit 18061c17c8ec ("powerpc/mm: Update PROTFAULT handling in the page > fault path") explains the details. > > Signed-off-by: Aneesh Kumar K.V (IBM) Reviewed-by: Christophe Leroy > --- > arch/powerpc/include/asm/book3s/64/pgtable.h | 10 ++ > arch/powerpc/mm/book3s64/hash_utils.c| 7 +++ > 2 files changed, 9 insertions(+), 8 deletions(-) > > diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h > b/arch/powerpc/include/asm/book3s/64/pgtable.h > index cb77eddca54b..927d585652bc 100644 > --- a/arch/powerpc/include/asm/book3s/64/pgtable.h > +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h > @@ -17,12 +17,6 @@ > #define _PAGE_EXEC 0x1 /* execute permission */ > #define _PAGE_WRITE 0x2 /* write access allowed */ > #define _PAGE_READ 0x4 /* read access allowed */ > -#define _PAGE_NA _PAGE_PRIVILEGED > -#define _PAGE_NAX_PAGE_EXEC > -#define _PAGE_RO _PAGE_READ > -#define _PAGE_ROX(_PAGE_READ | _PAGE_EXEC) > -#define _PAGE_RW (_PAGE_READ | _PAGE_WRITE) > -#define _PAGE_RWX(_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC) > #define _PAGE_PRIVILEGED0x8 /* kernel access only */ > #define _PAGE_SAO 0x00010 /* Strong access order */ > #define _PAGE_NON_IDEMPOTENT0x00020 /* non idempotent memory */ > @@ -532,8 +526,8 @@ static inline bool pte_user(pte_t pte) > static inline bool pte_access_permitted(pte_t pte, bool write) > { > /* > - * _PAGE_READ is needed for any access and will be > - * cleared for PROT_NONE > + * _PAGE_READ is needed for any access and will be cleared for > + * PROT_NONE. Execute-only mapping via PROT_EXEC also returns false. >*/ > if (!pte_present(pte) || !pte_user(pte) || !pte_read(pte)) > return false; > diff --git a/arch/powerpc/mm/book3s64/hash_utils.c > b/arch/powerpc/mm/book3s64/hash_utils.c > index ad2afa08e62e..0626a25b0d72 100644 > --- a/arch/powerpc/mm/book3s64/hash_utils.c > +++ b/arch/powerpc/mm/book3s64/hash_utils.c > @@ -310,9 +310,16 @@ unsigned long htab_convert_pte_flags(unsigned long > pteflags, unsigned long flags > else > rflags |= 0x3; > } > + VM_WARN_ONCE(!(pteflags & _PAGE_RWX), "no-access mapping > request"); > } else { > if (pteflags & _PAGE_RWX) > rflags |= 0x2; > + /* > + * We should never hit this in normal fault handling because > + * a permission check (check_pte_access()) will bubble this > + * to higher level linux handler even for PAGE_NONE. > + */ > + VM_WARN_ONCE(!(pteflags & _PAGE_RWX), "no-access mapping > request"); > if (!((pteflags & _PAGE_WRITE) && (pteflags & _PAGE_DIRTY))) > rflags |= 0x1; > }
Re: [PATCH] ocxl: fix driver function comment typo
Please add a description explaining why you want to do that change. When I grep I see cxlflash driver, I don't know what ocxlflash driver is: $ git grep ocxl_config_read_afu ... drivers/scsi/cxlflash/ocxl_hw.c:rc = ocxl_config_read_afu(pdev, fcfg, acfg, 0); drivers/scsi/cxlflash/ocxl_hw.c:dev_err(dev, "%s: ocxl_config_read_afu failed rc=%d\n", include/misc/ocxl.h:int ocxl_config_read_afu(struct pci_dev *dev, Christophe Le 05/12/2023 à 10:43, jiangyunshui a écrit : > [Vous ne recevez pas souvent de courriers de jiangyuns...@kylinos.cn. > Découvrez pourquoi ceci est important à > https://aka.ms/LearnAboutSenderIdentification ] > > Reported-by: k2ci > Signed-off-by: yunshui > --- > include/misc/ocxl.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/include/misc/ocxl.h b/include/misc/ocxl.h > index 3ed736da02c8..ef7d26009a36 100644 > --- a/include/misc/ocxl.h > +++ b/include/misc/ocxl.h > @@ -324,7 +324,7 @@ int ocxl_global_mmio_clear32(struct ocxl_afu *afu, size_t > offset, > int ocxl_global_mmio_clear64(struct ocxl_afu *afu, size_t offset, > enum ocxl_endian endian, u64 mask); > > -// Functions left here are for compatibility with the cxlflash driver > +// Functions left here are for compatibility with the ocxlflash driver > > /* >* Read the configuration space of a function for the AFU specified by > -- > 2.25.1 >
Re: [PATCH] MAINTAINERS: powerpc: Transfer PPC83XX to Christophe
Le 05/12/2023 à 06:12, Michael Ellerman a écrit : > Christophe volunteered[1] to maintain PPC83XX. > > 1: > https://lore.kernel.org/all/7b1bf4dc-d09d-35b8-f4df-16bf00429...@csgroup.eu/ > > Signed-off-by: Michael Ellerman Acked-by: Christophe Leroy > --- > MAINTAINERS | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 562d048863ee..d4efe48cc36a 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -12287,21 +12287,21 @@ S: Orphan > F: arch/powerpc/platforms/40x/ > F: arch/powerpc/platforms/44x/ > > -LINUX FOR POWERPC EMBEDDED PPC83XX AND PPC85XX > +LINUX FOR POWERPC EMBEDDED PPC85XX > M: Scott Wood > L: linuxppc-dev@lists.ozlabs.org > S: Odd fixes > T: git git://git.kernel.org/pub/scm/linux/kernel/git/scottwood/linux.git > F: Documentation/devicetree/bindings/cache/freescale-l2cache.txt > F: Documentation/devicetree/bindings/powerpc/fsl/ > -F: arch/powerpc/platforms/83xx/ > F: arch/powerpc/platforms/85xx/ > > -LINUX FOR POWERPC EMBEDDED PPC8XX > +LINUX FOR POWERPC EMBEDDED PPC8XX AND PPC83XX > M: Christophe Leroy > L: linuxppc-dev@lists.ozlabs.org > S: Maintained > F: arch/powerpc/platforms/8xx/ > +F: arch/powerpc/platforms/83xx/ > > LINUX KERNEL DUMP TEST MODULE (LKDTM) > M: Kees Cook
[PATCH] ocxl: fix driver function comment typo
Reported-by: k2ci Signed-off-by: yunshui --- include/misc/ocxl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/misc/ocxl.h b/include/misc/ocxl.h index 3ed736da02c8..ef7d26009a36 100644 --- a/include/misc/ocxl.h +++ b/include/misc/ocxl.h @@ -324,7 +324,7 @@ int ocxl_global_mmio_clear32(struct ocxl_afu *afu, size_t offset, int ocxl_global_mmio_clear64(struct ocxl_afu *afu, size_t offset, enum ocxl_endian endian, u64 mask); -// Functions left here are for compatibility with the cxlflash driver +// Functions left here are for compatibility with the ocxlflash driver /* * Read the configuration space of a function for the AFU specified by -- 2.25.1
Re: [PATCH v2 01/10] devm-helpers: introduce devm_mutex_init
On 12/4/23 20:05, George Stark wrote: Using of devm API leads to certain order of releasing resources. So all dependent resources which are not devm-wrapped should be deleted with respect to devm-release order. Mutex is one of such objects that often is bound to other resources and has no own devm wrapping. Since mutex_destroy() actually does nothing in non-debug builds frequently calling mutex_destroy() is just ignored which is safe for now but wrong formally and can lead to a problem if mutex_destroy() is extended so introduce devm_mutex_init(). Signed-off-by: George Stark --- include/linux/devm-helpers.h | 18 ++ 1 file changed, 18 insertions(+) diff --git a/include/linux/devm-helpers.h b/include/linux/devm-helpers.h index 74891802200d..2f56e476776f 100644 --- a/include/linux/devm-helpers.h +++ b/include/linux/devm-helpers.h @@ -76,4 +76,22 @@ static inline int devm_work_autocancel(struct device *dev, return devm_add_action(dev, devm_work_drop, w); } +static inline void devm_mutex_release(void *res) +{ + mutex_destroy(res); +} + +/** + * devm_mutex_init - Resource-managed mutex initialization + * @dev: Device which lifetime work is bound to Work? Copy-paste error? + * @lock: Pointer to a mutex + * + * Initialize mutex which is automatically destroyed when driver is detached. + */ +static inline int devm_mutex_init(struct device *dev, struct mutex *lock) +{ + mutex_init(lock); + return devm_add_action_or_reset(dev, devm_mutex_release, lock); +} + #endif Doesn't the mutex stuff need a header inclusion? Yours, -- Matti -- Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Re: [PATCH v3] powerpc/pseries/vas: Use usleep_range() to support HCALL delay
On 12/4/23 6:05 AM, Aneesh Kumar K.V (IBM) wrote: Haren Myneni writes: VAS allocate, modify and deallocate HCALLs returns H_LONG_BUSY_ORDER_1_MSEC or H_LONG_BUSY_ORDER_10_MSEC for busy delay and expects OS to reissue HCALL after that delay. But using msleep() will often sleep at least 20 msecs even though the hypervisor suggests OS reissue these HCALLs after 1 or 10msecs. The open and close VAS window functions hold mutex and then issue these HCALLs. So these operations can take longer than the necessary when multiple threads issue open or close window APIs simultaneously. So instead of msleep(), use usleep_range() to ensure sleep with the expected value before issuing HCALL again. Can you summarize if there an user observable impact for the current code? We have other code paths using msleep(get_longbusy_msec()). Should we audit those usages? As mentioned in the description, the open and close VAS window APIs can take longer with simultaneous calls, especially might affect the performance in the case of repeat open/close APIs for each compression request. On the large machine configuration which allows more simultaneous open windows (Ex: 240 cores provides 4800 VAS credits), the user can observe mutex contention around open/close HCAlls and hung-up traces in dmesg. I will repost the patch with this update in the commit message. I think applicable to use the similar approach for other HCALLs (like in rtas_busy_delay()) but I have not seen any impact so far with other HCALLs. So we can add this change later. Thanks Haren Signed-off-by: Haren Myneni Suggested-by: Nathan Lynch --- v1 -> v2: - Use usleep_range instead of using RTAS sleep routine as suggested by Nathan v2 -> v3: - Sleep 10MSecs even for HCALL delay > 10MSecs and the other commit / comemnt changes as suggested by Nathan and Ellerman. --- arch/powerpc/platforms/pseries/vas.c | 25 - 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c index 71d52a670d95..5cf81c564d4b 100644 --- a/arch/powerpc/platforms/pseries/vas.c +++ b/arch/powerpc/platforms/pseries/vas.c @@ -38,7 +38,30 @@ static long hcall_return_busy_check(long rc) { /* Check if we are stalled for some time */ if (H_IS_LONG_BUSY(rc)) { - msleep(get_longbusy_msecs(rc)); + unsigned int ms; + /* +* Allocate, Modify and Deallocate HCALLs returns +* H_LONG_BUSY_ORDER_1_MSEC or H_LONG_BUSY_ORDER_10_MSEC +* for the long delay. So the sleep time should always +* be either 1 or 10msecs, but in case if the HCALL +* returns the long delay > 10 msecs, clamp the sleep +* time to 10msecs. +*/ + ms = clamp(get_longbusy_msecs(rc), 1, 10); + + /* +* msleep() will often sleep at least 20 msecs even +* though the hypervisor suggests that the OS reissue +* HCALLs after 1 or 10msecs. Also the delay hint from +* the HCALL is just a suggestion. So OK to pause for +* less time than the hinted delay. Use usleep_range() +* to ensure we don't sleep much longer than actually +* needed. +* +* See Documentation/timers/timers-howto.rst for +* explanation of the range used here. +*/ + usleep_range(ms * 100, ms * 1000); rc = H_BUSY; } else if (rc == H_BUSY) { cond_resched(); -- 2.26.3
Re: [PATCH] cxl: Fix null pointer dereference in cxl_get_fd
Hi Fred, Thanks for your reply. But there is a question, whether we should return an error code in error path so that the caller of the 'cxl_get_fd' can know the specific reason. rather than just return NULL. Such as: - int rc, flags, fdtmp; + int rc = 0, flags, fdtmp; char *name = NULL; /* only allow one per context */ - if (ctx->mapping) - return ERR_PTR(-EEXIST); + if (ctx->mapping) { + rc = -EEXIST; + goto err; + } flags = O_RDWR | O_CLOEXEC; /* This code is similar to anon_inode_getfd() */ rc = get_unused_fd_flags(flags); - if (rc < 0) - return ERR_PTR(rc); + if (rc < 0) { + goto err; + } fdtmp = rc; name = kasprintf(GFP_KERNEL, "cxl:%d", ctx->pe); +if (!name) { + rc = -ENOMEM; + goto err_fd; +} file = cxl_getfile(name, fops, ctx, flags); kfree(name); @@ -434,6 +437,9 @@ struct file *cxl_get_fd(struct cxl_context *ctx, struct file_operations *fops, err_fd: put_unused_fd(fdtmp); +err: + if (rc) + return ERR_PTR(rc); return NULL; Thanks again, Kunwu On 2023/12/4 18:43, Frederic Barrat wrote: On 04/12/2023 03:07, Kunwu Chan wrote: kasprintf() returns a pointer to dynamically allocated memory which can be NULL upon failure. Fixes: bdecf76e319a ("cxl: Fix coredump generation when cxl_get_fd() is used") Signed-off-by: Kunwu Chan --- drivers/misc/cxl/api.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c index d85c56530863..bfd7ccd4d7e1 100644 --- a/drivers/misc/cxl/api.c +++ b/drivers/misc/cxl/api.c @@ -419,6 +419,10 @@ struct file *cxl_get_fd(struct cxl_context *ctx, struct file_operations *fops, fops = (struct file_operations *)_fops; name = kasprintf(GFP_KERNEL, "cxl:%d", ctx->pe); + if (!name) { + put_unused_fd(fdtmp); + return ERR_PTR(-ENOMEM); + } That works, but you might as well follow the existing error path: name = kasprintf(GFP_KERNEL, "cxl:%d", ctx->pe); if (!name) goto err_fd; Fred file = cxl_getfile(name, fops, ctx, flags); kfree(name); if (IS_ERR(file))