All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 3/4] coresight: trbe: Work around the invalid prohibited states
From: Suzuki K Poulose @ 2022-01-05 10:13 UTC (permalink / raw)
  To: Anshuman Khandual, linux-arm-kernel
  Cc: Catalin Marinas, Will Deacon, Mathieu Poirier, coresight,
	linux-doc, linux-kernel
In-Reply-To: <1641359159-22726-4-git-send-email-anshuman.khandual@arm.com>

Hi Anshuman

On 05/01/2022 05:05, Anshuman Khandual wrote:
> TRBE implementations affected by Arm erratum #2038923 might get TRBE into
> an inconsistent view on whether trace is prohibited within the CPU. As a
> result, the trace buffer or trace buffer state might be corrupted. This
> happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
> followed by just a single context synchronization event before execution
> changes from a context, in which trace is prohibited to one where it isn't,
> or vice versa. In these mentioned conditions, the view of whether trace is
> prohibited is inconsistent between parts of the CPU, and the trace buffer
> or the trace buffer state might be corrupted.
> 
> Work around this problem in the TRBE driver by preventing an inconsistent
> view of whether the trace is prohibited or not based on TRBLIMITR_EL1.E by
> immediately following a change to TRBLIMITR_EL1.E with at least one ISB
> instruction before an ERET, or two ISB instructions if no ERET is to take
> place. This adds a new cpu errata in arm64 errata framework and also
> updates TRBE driver as required.
> 
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose@arm.com>
> Cc: coresight@lists.linaro.org
> Cc: linux-doc@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
>   Documentation/arm64/silicon-errata.rst       |  2 +
>   arch/arm64/Kconfig                           | 23 ++++++++++
>   arch/arm64/kernel/cpu_errata.c               |  9 ++++
>   arch/arm64/tools/cpucaps                     |  1 +
>   drivers/hwtracing/coresight/coresight-trbe.c | 47 +++++++++++++++-----
>   5 files changed, 72 insertions(+), 10 deletions(-)

As with the previous patch, it may be a good idea to split the
patch to arm64 and trbe parts.

> 
> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
> index c9b30e6c2b6c..e0ef3e9a4b8b 100644
> --- a/Documentation/arm64/silicon-errata.rst
> +++ b/Documentation/arm64/silicon-errata.rst
> @@ -54,6 +54,8 @@ stable kernels.
>   +----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A510     | #2064142        | ARM64_ERRATUM_2064142       |
>   +----------------+-----------------+-----------------+-----------------------------+
> +| ARM            | Cortex-A510     | #2038923        | ARM64_ERRATUM_2038923       |
> ++----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
>   +----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 2105b68d88db..026e34fb6fad 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -796,6 +796,29 @@ config ARM64_ERRATUM_2064142
>   
>   	  If unsure, say Y.
>   
> +config ARM64_ERRATUM_2038923
> +	bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
> +	depends on CORESIGHT_TRBE
> +	default y
> +	help
> +	  This option adds the workaround for ARM Cortex-A510 erratum 2038923.
> +
> +	  Affected Cortex-A510 core might cause an inconsistent view on whether trace is
> +	  prohibited within the CPU. As a result, the trace buffer or trace buffer state
> +	  might be corrupted. This happens after TRBE buffer has been enabled by setting
> +	  TRBLIMITR_EL1.E, followed by just a single context synchronization event before
> +	  execution changes from a context, in which trace is prohibited to one where it
> +	  isn't, or vice versa. In these mentioned conditions, the view of whether trace
> +	  is prohibited is inconsistent between parts of the CPU, and the trace buffer or
> +	  the trace buffer state might be corrupted.
> +
> +	  Work around this in the driver by preventing an inconsistent view of whether the
> +	  trace is prohibited or not based on TRBLIMITR_EL1.E by immediately following a
> +	  change to TRBLIMITR_EL1.E with at least one ISB instruction before an ERET, or
> +	  two ISB instructions if no ERET is to take place.
> +
> +	  If unsure, say Y.
> +
>   config CAVIUM_ERRATUM_22375
>   	bool "Cavium erratum 22375, 24313"
>   	default y
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index cbb7d5a9aee7..60b0c1f1d912 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -607,6 +607,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>   		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
>   	},
>   #endif
> +#ifdef CONFIG_ARM64_ERRATUM_2038923
> +	{
> +		.desc = "ARM erratum 2038923",
> +		.capability = ARM64_WORKAROUND_2038923,
> +
> +		/* Cortex-A510 r0p0 - r0p2 */
> +		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
> +	},
> +#endif
>   	{
>   	}
>   };
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index fca3cb329e1d..45a06d36d080 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -56,6 +56,7 @@ WORKAROUND_1463225
>   WORKAROUND_1508412
>   WORKAROUND_1542419
>   WORKAROUND_2064142
> +WORKAROUND_2038923
>   WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>   WORKAROUND_TSB_FLUSH_FAILURE
>   WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index ec24b62b2cec..0689c6dab96d 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -92,11 +92,13 @@ struct trbe_buf {
>   #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
>   #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
>   #define TRBE_WORKAROUND_SYSREG_WRITE_FAILURE	2
> +#define TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE	3
>   
>   static int trbe_errata_cpucaps[] = {
>   	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>   	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
>   	[TRBE_WORKAROUND_SYSREG_WRITE_FAILURE] = ARM64_WORKAROUND_2064142,
> +	[TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE] = ARM64_WORKAROUND_2038923,
>   	-1,		/* Sentinel, must be the last entry */
>   };
>   
> @@ -174,6 +176,11 @@ static inline bool trbe_may_fail_sysreg_write(struct trbe_cpudata *cpudata)
>   	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_SYSREG_WRITE_FAILURE);
>   }
>   
> +static inline bool trbe_may_corrupt_with_enable(struct trbe_cpudata *cpudata)
> +{

minor nit: trbe_needs_{ctxt_sync, isb}_after_enable() ?

> +	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE);
> +}
> +
>   static int trbe_alloc_node(struct perf_event *event)
>   {
>   	if (event->cpu == -1)
> @@ -187,6 +194,30 @@ static inline void trbe_drain_buffer(void)
>   	dsb(nsh);
>   }
>   
> +static inline void set_trbe_enabled(struct trbe_cpudata *cpudata)
> +{
> +	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);

minor nit: This implies we do the TRBE programming in the following
manner in the common case (i.e, TRBE enabled in the beginning of a
session).
   -> set TRBE LIMIT
   -> read TRBE LIMIT
   -> set TRBE ENABLED

Could we please optimize this ? I believe the buf->trbe_limit
must hold the LIMITR value at any point in time. And thus this
function could simply be :

set_trbe_enabled(trbe_buf)
{
	limitr = trbe_buf->limit | LIMITR_ENABLE
	write(limitr, TRBLIMITR_EL1);
	...
}

Otherwise looks good to me

Suzuki

^ permalink raw reply

* [PATCH 0/2] Add toprgu reset-controller support for MT7986
From: Sam Shih @ 2022-01-05 10:04 UTC (permalink / raw)
  To: Wim Van Sebroeck, Guenter Roeck, Matthias Brugger, Philipp Zabel,
	Rob Herring, Ryder Lee, linux-kernel, linux-watchdog,
	linux-arm-kernel, linux-mediatek, devicetree
  Cc: John Crispin, Sam Shih

These patches aim to add watchdog toprgu reset-controller support
for MT7986.

Sam Shih (2):
  dt-bindings: reset: mt7986: Add reset-controller header file
  watchdog: mtk_wdt: mt7986: Add toprgu reset controller support

 drivers/watchdog/mtk_wdt.c                |  6 +++
 include/dt-bindings/reset/mt7986-resets.h | 55 +++++++++++++++++++++++
 2 files changed, 61 insertions(+)
 create mode 100644 include/dt-bindings/reset/mt7986-resets.h

-- 
2.29.2


_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

^ permalink raw reply

* [linux-next:pending-fixes] BUILD SUCCESS 99ae9b78c63395f986f1d9fd73f258139c8ec7bc
From: kernel test robot @ 2022-01-05 10:12 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linux Memory Management List

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git pending-fixes
branch HEAD: 99ae9b78c63395f986f1d9fd73f258139c8ec7bc  Merge branch 'for-linux-next-fixes' of git://anongit.freedesktop.org/drm/drm-misc

elapsed time: 725m

configs tested: 54
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
i386                   debian-10.3-kselftests
i386                              debian-10.3
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
riscv                    nommu_virt_defconfig
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                          rhel-8.3-func
x86_64                                  kexec

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org


^ permalink raw reply

* Re: [PATCH 7/8] mmc: jz4740: Make dev_pm_ops struct static
From: Jonathan Cameron @ 2022-01-05 10:12 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: Rafael J . Wysocki, Ulf Hansson, Jonathan Cameron,
	Lars-Peter Clausen, Linus Walleij, Arnd Bergmann, Len Brown,
	Pavel Machek, list, linux-iio, linux-kernel, linux-mips,
	linux-mmc, linux-pm
In-Reply-To: <20220104214214.198843-8-paul@crapouillou.net>

On Tue, 4 Jan 2022 21:42:13 +0000
Paul Cercueil <paul@crapouillou.net> wrote:

> The new DEFINE_SIMPLE_DEV_PM_OPS() macro does not set the "static"
> qualifier anymore, so we can add it here, as the underlying dev_pm_ops
> struct is only used in this file.
> 
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

> ---
>  drivers/mmc/host/jz4740_mmc.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
> index 7693236c946f..7ab1b38a7be5 100644
> --- a/drivers/mmc/host/jz4740_mmc.c
> +++ b/drivers/mmc/host/jz4740_mmc.c
> @@ -1128,8 +1128,8 @@ static int jz4740_mmc_resume(struct device *dev)
>  	return pinctrl_select_default_state(dev);
>  }
>  
> -DEFINE_SIMPLE_DEV_PM_OPS(jz4740_mmc_pm_ops, jz4740_mmc_suspend,
> -	jz4740_mmc_resume);
> +static DEFINE_SIMPLE_DEV_PM_OPS(jz4740_mmc_pm_ops, jz4740_mmc_suspend,
> +				jz4740_mmc_resume);
>  
>  static struct platform_driver jz4740_mmc_driver = {
>  	.probe = jz4740_mmc_probe,


^ permalink raw reply

* Re: [PATCH 6/8] mmc: mxc: Make dev_pm_ops struct static
From: Jonathan Cameron @ 2022-01-05 10:12 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: Rafael J . Wysocki, Ulf Hansson, Jonathan Cameron,
	Lars-Peter Clausen, Linus Walleij, Arnd Bergmann, Len Brown,
	Pavel Machek, list, linux-iio, linux-kernel, linux-mips,
	linux-mmc, linux-pm
In-Reply-To: <20220104214214.198843-7-paul@crapouillou.net>

On Tue, 4 Jan 2022 21:42:12 +0000
Paul Cercueil <paul@crapouillou.net> wrote:

> The new DEFINE_SIMPLE_DEV_PM_OPS() macro does not set the "static"
> qualifier anymore, so we can add it here, as the underlying dev_pm_ops
> struct is only used in this file.
> 
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>
FWIW on this trivial patch

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

> ---
>  drivers/mmc/host/mxcmmc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
> index 98c218bd6669..40b6878bea6c 100644
> --- a/drivers/mmc/host/mxcmmc.c
> +++ b/drivers/mmc/host/mxcmmc.c
> @@ -1210,7 +1210,7 @@ static int mxcmci_resume(struct device *dev)
>  	return ret;
>  }
>  
> -DEFINE_SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume);
> +static DEFINE_SIMPLE_DEV_PM_OPS(mxcmci_pm_ops, mxcmci_suspend, mxcmci_resume);
>  
>  static struct platform_driver mxcmci_driver = {
>  	.probe		= mxcmci_probe,


^ permalink raw reply

* Re: [Intel-gfx] [PATCH 2/2] drm/i915/uncore: rename i915_reg_read_ioctl intel_uncore_reg_read_ioctl
From: Tvrtko Ursulin @ 2022-01-05 10:11 UTC (permalink / raw)
  To: Jani Nikula, intel-gfx
In-Reply-To: <20220105100520.976092-2-jani.nikula@intel.com>


On 05/01/2022 10:05, Jani Nikula wrote:
> Follow the usual naming convention.

But intel_uncore_ prefix usually means functions takes intel_uncore as 
the first argument.

Maybe solution here is that i915_reg_read_ioctl does not belong in 
intel_uncore.c, it being the UAPI layer thing? I guess arguments could 
be made for either way.

Regards,

Tvrtko

> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>   drivers/gpu/drm/i915/i915_driver.c  | 2 +-
>   drivers/gpu/drm/i915/intel_uncore.c | 4 ++--
>   drivers/gpu/drm/i915/intel_uncore.h | 4 ++--
>   3 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c
> index 95174938b160..f9a494e159dc 100644
> --- a/drivers/gpu/drm/i915/i915_driver.c
> +++ b/drivers/gpu/drm/i915/i915_driver.c
> @@ -1805,7 +1805,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = {
>   	DRM_IOCTL_DEF_DRV(I915_GEM_WAIT, i915_gem_wait_ioctl, DRM_RENDER_ALLOW),
>   	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_CREATE_EXT, i915_gem_context_create_ioctl, DRM_RENDER_ALLOW),
>   	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_DESTROY, i915_gem_context_destroy_ioctl, DRM_RENDER_ALLOW),
> -	DRM_IOCTL_DEF_DRV(I915_REG_READ, i915_reg_read_ioctl, DRM_RENDER_ALLOW),
> +	DRM_IOCTL_DEF_DRV(I915_REG_READ, intel_uncore_reg_read_ioctl, DRM_RENDER_ALLOW),
>   	DRM_IOCTL_DEF_DRV(I915_GET_RESET_STATS, i915_gem_context_reset_stats_ioctl, DRM_RENDER_ALLOW),
>   	DRM_IOCTL_DEF_DRV(I915_GEM_USERPTR, i915_gem_userptr_ioctl, DRM_RENDER_ALLOW),
>   	DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW),
> diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
> index fc25ebf1a593..33f95bb2d3d5 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.c
> +++ b/drivers/gpu/drm/i915/intel_uncore.c
> @@ -2269,8 +2269,8 @@ static const struct reg_whitelist {
>   	.size = 8
>   } };
>   
> -int i915_reg_read_ioctl(struct drm_device *dev,
> -			void *data, struct drm_file *file)
> +int intel_uncore_reg_read_ioctl(struct drm_device *dev,
> +				void *data, struct drm_file *file)
>   {
>   	struct drm_i915_private *i915 = to_i915(dev);
>   	struct intel_uncore *uncore = &i915->uncore;
> diff --git a/drivers/gpu/drm/i915/intel_uncore.h b/drivers/gpu/drm/i915/intel_uncore.h
> index 3a87bbd906f8..697ac4586159 100644
> --- a/drivers/gpu/drm/i915/intel_uncore.h
> +++ b/drivers/gpu/drm/i915/intel_uncore.h
> @@ -457,7 +457,7 @@ static inline int intel_uncore_write_and_verify(struct intel_uncore *uncore,
>   #define raw_reg_write(base, reg, value) \
>   	writel(value, base + i915_mmio_reg_offset(reg))
>   
> -int i915_reg_read_ioctl(struct drm_device *dev, void *data,
> -			struct drm_file *file);
> +int intel_uncore_reg_read_ioctl(struct drm_device *dev, void *data,
> +				struct drm_file *file);
>   
>   #endif /* !__INTEL_UNCORE_H__ */
> 

^ permalink raw reply

* drivers/gpu/drm/amd/amdgpu/../display/dc/dcn303/dcn303_resource.c:533 dcn303_stream_encoder_create() error: buffer overflow 'stream_enc_regs' 2 <= 4
From: Dan Carpenter @ 2022-01-05 10:11 UTC (permalink / raw)
  To: kbuild, Aurabindo Pillai
  Cc: lkp, kbuild-all, linux-kernel, Alex Deucher, Chris Park

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head:   3f667b5d4053ad54aee13dab5c94f04ff75ddfdf
commit: cd6d421e3d1ad5926b74091254e345db730e7706 drm/amd/display: Initial DC support for Beige Goby
config: x86_64-randconfig-m001-20211207 (https://download.01.org/0day-ci/archive/20211219/202112190934.db7anVBT-lkp@intel.com/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

New smatch warnings:
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn303/dcn303_resource.c:533 dcn303_stream_encoder_create() error: buffer overflow 'stream_enc_regs' 2 <= 4

Old smatch warnings:
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn303/dcn303_resource.c:531 dcn303_stream_encoder_create() warn: possible memory leak of 'enc1'

vim +/stream_enc_regs +533 drivers/gpu/drm/amd/amdgpu/../display/dc/dcn303/dcn303_resource.c

cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  511  static struct stream_encoder *dcn303_stream_encoder_create(enum engine_id eng_id, struct dc_context *ctx)
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  512  {
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  513  	struct dcn10_stream_encoder *enc1;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  514  	struct vpg *vpg;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  515  	struct afmt *afmt;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  516  	int vpg_inst;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  517  	int afmt_inst;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  518  
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  519  	/* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  520  	if (eng_id <= ENGINE_ID_DIGE) {
                                                            ^^^^^^^^^^^^^^^^^^^^^^^^
eng_id <= 4

cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  521  		vpg_inst = eng_id;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  522  		afmt_inst = eng_id;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  523  	} else
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  524  		return NULL;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  525  
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  526  	enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  527  	vpg = dcn303_vpg_create(ctx, vpg_inst);
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  528  	afmt = dcn303_afmt_create(ctx, afmt_inst);
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  529  
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  530  	if (!enc1 || !vpg || !afmt)
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  531  		return NULL;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  532  
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15 @533  	dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id, vpg, afmt, &stream_enc_regs[eng_id],
                                                                                                                                       ^^^^^^^^^^^^^^^^^^^^^^^^
Out of bounds.  (I have not reviewed the context but these warnings are
pretty reliable).

cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  534  			&se_shift, &se_mask);
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  535  
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  536  	return &enc1->base;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  537  }

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org


^ permalink raw reply

* Re: [docs] [PATCH] bitbake: doc: bitbake-user-manual: Add more explanations to OVERRIDES
From: Simon Eugster @ 2022-01-05 10:11 UTC (permalink / raw)
  To: Michael Opdenacker; +Cc: bitbake-devel, docs
In-Reply-To: <42d3ff93-33a1-e751-b0ff-974c8ecb4858@bootlin.com>

[-- Attachment #1: Type: text/plain, Size: 4442 bytes --]

Hi Michael,

Am Mi., 15. Dez. 2021 um 11:46 Uhr schrieb Michael Opdenacker <
michael.opdenacker@bootlin.com>:

> Hi Simon,
>
> Many thanks for the new version of your patch!
> See my questions below...
>
> On 12/15/21 10:25 AM, Simon A. Eugster wrote:
> > Signed-off-by: Simon A. Eugster <simon.eu@gmail.com>
> > ---
> >  .../bitbake-user-manual-metadata.rst          | 28 ++++++++++++-------
> >  1 file changed, 18 insertions(+), 10 deletions(-)
> >
> > diff --git a/doc/bitbake-user-manual/bitbake-user-manual-metadata.rst
> b/doc/bitbake-user-manual/bitbake-user-manual-metadata.rst
> > index d802a8d3..fc4f5d13 100644
> > --- a/doc/bitbake-user-manual/bitbake-user-manual-metadata.rst
> > +++ b/doc/bitbake-user-manual/bitbake-user-manual-metadata.rst
> > @@ -300,6 +300,12 @@ It is also possible to append and prepend to shell
> functions and
> >  BitBake-style Python functions. See the
> ":ref:`bitbake-user-manual/bitbake-user-manual-metadata:shell functions`"
> and ":ref:`bitbake-user-manual/bitbake-user-manual-metadata:bitbake-style
> python functions`"
> >  sections for examples.
> >
> > +.. note::
> > +
> > +   Before Honister (3.4), override style used ``_`` instead of ``:``,
> so you will
> > +   still find a lot of documentation using “_append”, “_prepend”, and
> > +   “_remove”.
> > +
>
>
> I don't have anything about this text, but I wonder whether we should
> mention the old syntax in the current docs.
> Thoughts anyone?
>

I added this because I (as a new user) found it very confusing to find all
the _ style syntax in guides online and no mention of it in the docs. I
would have expected such a note.


> >  .. _removing-override-style-syntax:
> >
> >  Removal (Override Style Syntax)
> > @@ -517,20 +523,22 @@ variable.
> >  -  *Selecting a Variable:* The :term:`OVERRIDES` variable is a
> >     colon-character-separated list that contains items for which you want
> >     to satisfy conditions. Thus, if you have a variable that is
> > -   conditional on "arm", and "arm" is in :term:`OVERRIDES`, then the
> > +   conditional on "arm", and "arm" is listed in :term:`OVERRIDES`, then
> the
> >     "arm"-specific version of the variable is used rather than the
> >     non-conditional version. Here is an example::
> >
> > -      OVERRIDES = "architecture:os:machine"
> > +      # Typically, OVERRIDES contains something like
> architecture:os:machine
> > +      OVERRIDES = "linux:arm"
>
>
> Here you quote an example with two items, but this doesn't align with
> the typical contents with three items you mention in the comment that
> you added.
> By the way, according to the below text, didn't you mean?
>
> OVERRIDES = "foo:linux:arm"
>
> It looks like a good idea to have this comment; this way you can give a
> concrete example. In my opinion, "foo" is vague, what about instead?
>
> OVERRIDES = "arm:linux:beaglebone"
>

Yes, will change that!


> >        TEST = "default"
> > -      TEST_os = "osspecific"
> > -      TEST_nooverride = "othercondvalue"
> > +      TEST:arm = "armspecific"
> > +      TEST:nooverride = "othercondvalue"
> >
> > -   In this example, the :term:`OVERRIDES`
> > -   variable lists three overrides: "architecture", "os", and "machine".
> > -   The variable ``TEST`` by itself has a default value of "default". You
> > -   select the os-specific version of the ``TEST`` variable by appending
> > -   the "os" override to the variable (i.e. ``TEST_os``).
> > +   In this example, the :term:`OVERRIDES` variable lists three
> > +   overrides: "foo", "linux", and "arm". The variable ``TEST`` by itself
> > +   has a default value of "default", and the value of the “arm” specific
> > +   version “armspecific” is used because :term:`OVERRIDES` contains
> > +   “arm”. The “nooverride” specific version is not used because
> > +   :term:`OVERRIDES` does not contain “nooverride”.
> >
> >     To better understand this, consider a practical example that assumes
> >     an OpenEmbedded metadata-based Linux kernel recipe file. The
> > @@ -552,7 +560,7 @@ variable.
> >
> >        DEPENDS = "glibc ncurses"
> >        OVERRIDES = "machine:local"
> > -      DEPENDS:append:machine = "libmad"
> > +      DEPENDS:append:machine = " libmad"
> >
> >     In this example, :term:`DEPENDS` becomes "glibc ncurses libmad".
>

Thanks,
Simon

[-- Attachment #2: Type: text/html, Size: 5959 bytes --]

^ permalink raw reply

* drivers/gpu/drm/amd/amdgpu/../display/dc/dcn303/dcn303_resource.c:533 dcn303_stream_encoder_create() error: buffer overflow 'stream_enc_regs' 2 <= 4
From: Dan Carpenter @ 2022-01-05 10:11 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3578 bytes --]

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head:   3f667b5d4053ad54aee13dab5c94f04ff75ddfdf
commit: cd6d421e3d1ad5926b74091254e345db730e7706 drm/amd/display: Initial DC support for Beige Goby
config: x86_64-randconfig-m001-20211207 (https://download.01.org/0day-ci/archive/20211219/202112190934.db7anVBT-lkp(a)intel.com/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

New smatch warnings:
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn303/dcn303_resource.c:533 dcn303_stream_encoder_create() error: buffer overflow 'stream_enc_regs' 2 <= 4

Old smatch warnings:
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn303/dcn303_resource.c:531 dcn303_stream_encoder_create() warn: possible memory leak of 'enc1'

vim +/stream_enc_regs +533 drivers/gpu/drm/amd/amdgpu/../display/dc/dcn303/dcn303_resource.c

cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  511  static struct stream_encoder *dcn303_stream_encoder_create(enum engine_id eng_id, struct dc_context *ctx)
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  512  {
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  513  	struct dcn10_stream_encoder *enc1;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  514  	struct vpg *vpg;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  515  	struct afmt *afmt;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  516  	int vpg_inst;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  517  	int afmt_inst;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  518  
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  519  	/* Mapping of VPG, AFMT, DME register blocks to DIO block instance */
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  520  	if (eng_id <= ENGINE_ID_DIGE) {
                                                            ^^^^^^^^^^^^^^^^^^^^^^^^
eng_id <= 4

cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  521  		vpg_inst = eng_id;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  522  		afmt_inst = eng_id;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  523  	} else
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  524  		return NULL;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  525  
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  526  	enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  527  	vpg = dcn303_vpg_create(ctx, vpg_inst);
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  528  	afmt = dcn303_afmt_create(ctx, afmt_inst);
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  529  
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  530  	if (!enc1 || !vpg || !afmt)
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  531  		return NULL;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  532  
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15 @533  	dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios, eng_id, vpg, afmt, &stream_enc_regs[eng_id],
                                                                                                                                       ^^^^^^^^^^^^^^^^^^^^^^^^
Out of bounds.  (I have not reviewed the context but these warnings are
pretty reliable).

cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  534  			&se_shift, &se_mask);
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  535  
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  536  	return &enc1->base;
cd6d421e3d1ad5 Aurabindo Pillai 2021-03-15  537  }

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

^ permalink raw reply

* Re: [PATCH 8/8] iio: gyro: mpu3050: Use new PM macros
From: Jonathan Cameron @ 2022-01-05 10:11 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: Rafael J . Wysocki, Ulf Hansson, Jonathan Cameron,
	Lars-Peter Clausen, Linus Walleij, Arnd Bergmann, Len Brown,
	Pavel Machek, list, linux-iio, linux-kernel, linux-mips,
	linux-mmc, linux-pm
In-Reply-To: <20220104214214.198843-9-paul@crapouillou.net>

On Tue, 4 Jan 2022 21:42:14 +0000
Paul Cercueil <paul@crapouillou.net> wrote:

> Use the new EXPORT_RUNTIME_DEV_PM_OPS() macro. It allows the underlying
> dev_pm_ops struct as well as the suspend/resume callbacks to be detected
> as dead code in the case where CONFIG_PM is disabled, without having to
> wrap everything inside #ifdef CONFIG_PM guards.
> 
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>

Hohum - bad choice of example. These shouldn't be exported as only used within
the same module ;)  No one ever wrote the other bus interface (and the part is
ancient so I can't see it happening now) hence whilst there are two files, they
are built into a single module.  There is a comment about this in the Makefile.

Jonathan


> ---
>  drivers/iio/gyro/mpu3050-core.c | 13 ++++---------
>  drivers/iio/gyro/mpu3050-i2c.c  |  2 +-
>  2 files changed, 5 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c
> index ea387efab62d..7d6721e268fe 100644
> --- a/drivers/iio/gyro/mpu3050-core.c
> +++ b/drivers/iio/gyro/mpu3050-core.c
> @@ -1281,7 +1281,6 @@ int mpu3050_common_remove(struct device *dev)
>  }
>  EXPORT_SYMBOL(mpu3050_common_remove);
>  
> -#ifdef CONFIG_PM
>  static int mpu3050_runtime_suspend(struct device *dev)
>  {
>  	return mpu3050_power_down(iio_priv(dev_get_drvdata(dev)));
> @@ -1291,15 +1290,11 @@ static int mpu3050_runtime_resume(struct device *dev)
>  {
>  	return mpu3050_power_up(iio_priv(dev_get_drvdata(dev)));
>  }
> -#endif /* CONFIG_PM */
>  
> -const struct dev_pm_ops mpu3050_dev_pm_ops = {
> -	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> -				pm_runtime_force_resume)
> -	SET_RUNTIME_PM_OPS(mpu3050_runtime_suspend,
> -			   mpu3050_runtime_resume, NULL)
> -};
> -EXPORT_SYMBOL(mpu3050_dev_pm_ops);
> +EXPORT_RUNTIME_DEV_PM_OPS(mpu3050_dev_pm_ops,
> +			  mpu3050_runtime_suspend,
> +			  mpu3050_runtime_resume,
> +			  NULL);
>  
>  MODULE_AUTHOR("Linus Walleij");
>  MODULE_DESCRIPTION("MPU3050 gyroscope driver");
> diff --git a/drivers/iio/gyro/mpu3050-i2c.c b/drivers/iio/gyro/mpu3050-i2c.c
> index ef5bcbc4b45b..820133cad601 100644
> --- a/drivers/iio/gyro/mpu3050-i2c.c
> +++ b/drivers/iio/gyro/mpu3050-i2c.c
> @@ -114,7 +114,7 @@ static struct i2c_driver mpu3050_i2c_driver = {
>  	.driver = {
>  		.of_match_table = mpu3050_i2c_of_match,
>  		.name = "mpu3050-i2c",
> -		.pm = &mpu3050_dev_pm_ops,
> +		.pm = pm_ptr(&mpu3050_dev_pm_ops),
>  	},
>  };
>  module_i2c_driver(mpu3050_i2c_driver);


^ permalink raw reply

* Re: #KCIDB v9 release
From: Nikolai Kondrashov @ 2022-01-05 10:10 UTC (permalink / raw)
  To: Cristian Marussi, Tim Bird, Dmitry Vyukov, Guillaume Tucker,
	Alice Ferrazzi, Iñaki Malerba, kernelci, Vishal Bhoj,
	automated-testing
In-Reply-To: <5e7e52fd-8318-7ac0-b4d1-fd65acab6cb8@redhat.com>

On 1/3/22 13:49, Nikolai Kondrashov wrote:
> Hi everyone,
> 
> On 12/1/21 20:01, Nikolai Kondrashov wrote:
>> I'm proud to announce the release and deployment of KCIDB v9.
>>
>> Please see the detailed list of changes at
>> https://github.com/kernelci/kcidb/releases/tag/v9
>>
>> Most important changes are listed below.
> ...
>> * Rename the submission queue topic for production from "kernelci_new" to
>>    "kcidb_new", and for playground from "playground_kernelci_new" to
>>    "playground_kcidb_new". This is done to unify KCIDB namespace inside Google
>>    Cloud and to help automate deployments. The old names will keep working
>>    until Dec 31.
> ...
>> * Remember to switch to the new submission topics (above) by Dec 31!
> 
> I see that there's still some data being sent to the old topics "kernelci_new" 
> and "playground_kernelci_new". Please switch to using "kcidb_new" and 
> "playground_kcidb_new" instead, respectively.
> 
> I will remove the old ones on Wednesday at 12:00 EET. After that, submissions 
> to the old topics will be failing and no data sent there will reach KCIDB.

Old topics are removed now. Please use the new ones instead.

Nick


^ permalink raw reply

* Re: [PATCH 1/5] tools/libxl: Mark pointer args of many functions constant
From: Anthony PERARD @ 2022-01-05 10:09 UTC (permalink / raw)
  To: Elliott Mitchell; +Cc: xen-devel, Wei Liu, Juergen Gross
In-Reply-To: <80dd561339dbe54f1ed2c2302ace389e87d445fe.1640590794.git.ehem+xen@m5p.com>

On Fri, Dec 18, 2020 at 01:37:44PM -0800, Elliott Mitchell wrote:
> Anything *_is_empty(), *_is_default(), or *_gen_json() is going to be
> examining the pointed to thing, not modifying it.  This potentially
> results in higher-performance output.  This also allows spreading
> constants further, allowing more checking and security.
> 
> Signed-off-by: Elliott Mitchell <ehem+xen@m5p.com>

This patch doesn't build.

    libxl_cpuid.c:510:17: error: conflicting types for ‘libxl_cpuid_policy_list_gen_json’
      510 | yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand,
          |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    In file included from libxl_internal.h:89,
                     from libxl_cpuid.c:15:
    /home/sheep/work/xen/tools/libs/light/../../../tools/include/libxl_json.h:30:17: note: previous declaration of ‘libxl_cpuid_policy_list_gen_json’ was here
       30 | yajl_gen_status libxl_cpuid_policy_list_gen_json(yajl_gen hand,
          |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Also we talked about this patch before, in
    https://lore.kernel.org/xen-devel/YImXfc4oaPgWzkeT@perard/

Cheers,

-- 
Anthony PERARD


^ permalink raw reply

* Re: [PATCH 2/2] KVM: x86: Forbid KVM_SET_CPUID{,2} after KVM_RUN
From: Vitaly Kuznetsov @ 2022-01-05 10:09 UTC (permalink / raw)
  To: Paolo Bonzini, Igor Mammedov
  Cc: kvm, Sean Christopherson, Wanpeng Li, Jim Mattson, linux-kernel
In-Reply-To: <ceb63787-b057-13db-4624-b430c51625f1@redhat.com>

Paolo Bonzini <pbonzini@redhat.com> writes:

> On 1/3/22 13:56, Vitaly Kuznetsov wrote:
>>   'allowlist' of things which can change (and put
>> *APICids there) and only fail KVM_SET_CPUID{,2} when we see something
>> else changing.
>
> We could also go the other way and only deny changes that result in 
> changed CPU caps.  That should be easier to implement since we have 
> already a mapping from CPU capability words to CPUID leaves and registers.
>

Good idea, I'll look into it (if noone beats me to it).

-- 
Vitaly


^ permalink raw reply

* Re: 'Re: [PATCH] drivers/android: remove redundant ret variable'
From: Greg KH @ 2022-01-05 10:09 UTC (permalink / raw)
  To: cgel.zte
  Cc: arve, chi.minghao, christian, hridya, joel, linux-kernel, maco,
	surenb, tkjos, zealci
In-Reply-To: <20220105091942.616961-1-chi.minghao@zte.com.cn>

On Wed, Jan 05, 2022 at 09:19:42AM +0000, cgel.zte@gmail.com wrote:
> I found that there are indeed some optimizations
> after removing the redundancy.

You stripped off all context, making this impossible to remember what
you are responding to :(

> 
> For example:
> 
> int foo(int a, int b)
> {
>         int ret;
>         ret = a>b ? a: b;
>         return ret;
> }
> int main()
> {
>         int val;
>         val = foo(7,2);
>         return 0;
> }
> 
> and
> 
> int foo(int a, int b)
> {
>         return a>b ? a: b;
> }
> int main()
> {
>         int val;
>         val = foo(7,2);
>         return 0;
> }
> 
> The corresponding disassembly code is as follows:
> 
>     1129:       f3 0f 1e fa             endbr64 
>     112d:       55                      push   %rbp
>     112e:       48 89 e5                mov    %rsp,%rbp
>     1131:       89 7d fc                mov    %edi,-0x4(%rbp)
>     1134:       89 75 f8                mov    %esi,-0x8(%rbp)
>     1137:       8b 45 fc                mov    -0x4(%rbp),%eax
>     113a:       39 45 f8                cmp    %eax,-0x8(%rbp)
>     113d:       0f 4d 45 f8             cmovge -0x8(%rbp),%eax
>     1141:       5d                      pop    %rbp
>     1142:       c3                      retq
> 
> and
> 
>     1129:       f3 0f 1e fa             endbr64 
>     112d:       55                      push   %rbp
>     112e:       48 89 e5                mov    %rsp,%rbp
>     1131:       89 7d ec                mov    %edi,-0x14(%rbp)
>     1134:       89 75 e8                mov    %esi,-0x18(%rbp)
>     1137:       8b 45 ec                mov    -0x14(%rbp),%eax
>     113a:       39 45 e8                cmp    %eax,-0x18(%rbp)
>     113d:       0f 4d 45 e8             cmovge -0x18(%rbp),%eax
>     1141:       89 45 fc                mov    %eax,-0x4(%rbp)
>     1144:       8b 45 fc                mov    -0x4(%rbp),%eax
>     1147:       5d                      pop    %rbp
>     1148:       c3                      retq
> 
> After removing the redundancy, the compiler does
> have some optimizations

As I said on your other email, look at the kernel built files please,
they should be much different from your tiny example above.

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH] platform: finally disallow IRQ0 in platform_get_irq() and its ilk
From: Andy Shevchenko @ 2022-01-05 10:09 UTC (permalink / raw)
  To: Sergey Shtylyov
  Cc: Andy Shevchenko, Greg Kroah-Hartman, Rafael J. Wysocki,
	Linux Kernel Mailing List
In-Reply-To: <8a415980-990b-abae-6f60-dedd0c199583@omp.ru>

On Wed, Jan 5, 2022 at 9:40 AM Sergey Shtylyov <s.shtylyov@omp.ru> wrote:
> On 12/10/21 2:17 PM, Andy Shevchenko wrote:

> >>> Wanna help?
> >>
> >>    No, I'm afraid you're on your own here...
>
>    Tell me please, how far you've got with this by now?
>    (I've already started to add the fixups to your patch -- unfortunately, this change has to be
> done atomically, not piecemeal.)

I just returned from vacation and will have another one soon, I don't
think I will be doing much for the next couple of weeks.


> >>>> Fixes: a85a6c86c25b ("driver core: platform: Clarify that IRQ 0 is invalid")
> >>>
> >>> Not sure.
> >>
> >>    Why? It fixes gthe IRQ0 problem, so that you don't have to check for IRQ0 in many callers
> >> (for the subsytems that treat 0 as s/th special, like polling mode)... If you have something
> >> to improve, you can do that atop of this patch...
> >
> > Because first we need to fix all users of platform_get_irq_optional().
>
>    I still don't understand why your issue should be fixed 1st -- but I don't really care about
> the order...

See my other comments on the discussion.
The rough roadmap is:
1) check which drivers are still subjects of vIRQ0 which is retrieved
via IRQ resource
2) fix them accordingly (for example, by transforming to IRQ domains)
3) convert platform_get_irq() and Co (including optional variants) to
follow the pattern
 a) non-optional APIs never return 0
 b) optional APIs return negative error, or positive vIRQ or 0 when
IRQ not found

Alternatively you may put a big comment in the drivers first and use
platform_get_resource() for retrieving IRQ0 without WARN(). Then they
will be subject to fix later on.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply

* Re: [PATCH misc-next] drivers/misc: remove redundant rc variable
From: Greg KH @ 2022-01-05 10:08 UTC (permalink / raw)
  To: cgel.zte
  Cc: arnd, chi.minghao, fkassabri, linux-kernel, obitton, ogabbay,
	osharabi, ynudelman, zealci
In-Reply-To: <20220105092229.617027-1-chi.minghao@zte.com.cn>

On Wed, Jan 05, 2022 at 09:22:29AM +0000, cgel.zte@gmail.com wrote:
> I found that there are indeed some optimizations
> after removing the redundancy.
> 
> For example:
> 
> int foo(int a, int b)
> {
>         int ret;
>         ret = a>b ? a: b;
>         return ret;
> }
> int main()
> {
>         int val;
>         val = foo(7,2);
>         return 0;
> }
> 
> and
> 
> int foo(int a, int b)
> {
>         return a>b ? a: b;
> }
> int main()
> {
>         int val;
>         val = foo(7,2);
>         return 0;
> }
> 
> The corresponding disassembly code is as follows:
> 
>     1129:       f3 0f 1e fa             endbr64 
>     112d:       55                      push   %rbp
>     112e:       48 89 e5                mov    %rsp,%rbp
>     1131:       89 7d fc                mov    %edi,-0x4(%rbp)
>     1134:       89 75 f8                mov    %esi,-0x8(%rbp)
>     1137:       8b 45 fc                mov    -0x4(%rbp),%eax
>     113a:       39 45 f8                cmp    %eax,-0x8(%rbp)
>     113d:       0f 4d 45 f8             cmovge -0x8(%rbp),%eax
>     1141:       5d                      pop    %rbp
>     1142:       c3                      retq
> 
> and
> 
>     1129:       f3 0f 1e fa             endbr64 
>     112d:       55                      push   %rbp
>     112e:       48 89 e5                mov    %rsp,%rbp
>     1131:       89 7d ec                mov    %edi,-0x14(%rbp)
>     1134:       89 75 e8                mov    %esi,-0x18(%rbp)
>     1137:       8b 45 ec                mov    -0x14(%rbp),%eax
>     113a:       39 45 e8                cmp    %eax,-0x18(%rbp)
>     113d:       0f 4d 45 e8             cmovge -0x18(%rbp),%eax
>     1141:       89 45 fc                mov    %eax,-0x4(%rbp)
>     1144:       8b 45 fc                mov    -0x4(%rbp),%eax
>     1147:       5d                      pop    %rbp
>     1148:       c3                      retq
> 
> After removing the redundancy, the compiler does
> have some optimizations

Please look at the actual output of the kernel files, the build options
that the kernel enforces should not cause a difference here.

thanks,

greg k-h

^ permalink raw reply

* Problem loading eBPF program on Kernel 4.18 (best with CO:RE): -EINVAL
From: Buchberger, Dennis @ 2022-01-05 10:03 UTC (permalink / raw)
  To: bpf@vger.kernel.org

Hello :)

I am currently having a problem and hope you can help me: My goal is to develop a BPF-program (see below) on a development machine and then deploy it to another machine to run it there using BPF CO:RE.
But the program does not load; bpf_object__load returns -EINVAL.

Development machine:
- Ubuntu 20.04 LTS
- Linux 5.4.0-90-generic x86_64
- Kernel compiled with CONFIG_DEBUG_INFO_BTF=y, so BTF is available under /sys/kernel/btf/vmlinux
- clang version: 10.0.0-4ubuntu1
- llc version: 10.0.0

Target machine:
- Ubuntu 18.10
- Linux 4.18.0-25-generic x86_64
- clang version: 13.0.0
- llc version: 13.0.0

As the target kernel does not support CONFIG_DEBUG_INFO_BTF, I used pahole -J (v1.22) to create vmlinux file with BTF info embedded there.
Basically, I followed this mails: https://lore.kernel.org/bpf/CADmGQ+1euj7Uv9e8UyZMMXDiYAKqXe9=GSTBFNbbg1E0R-ejyg@mail.gmail.com/

Right now, the bpf program is just a uProbe for a simple test app, which writes some output to the tracing pipe. As Kernel 4.18. does not support global data for bpf programs, I had to remove (comment out) the bpf_trace_printk statements.
On the development machine, it works fine. But on the target machine, loading the program fails: libbpf: load bpf program failed: Invalid argument (full libbpf log see below).
When compiling the programs on the target machine without using CO:RE, I get a similar error (invalid argument, -22).
What could be the problem? I don't think the eBPF program uses anything that is available on Kernel 5.4.0 and not available on the system with Kernel 4.18, does it?

Thanks in advance for your help.
Best
Dennis




============ log ============

sudo ./ebpf 
libbpf: loading main.bpf.o
libbpf: elf: section(3) kprobe/, size 272, link 0, flags 6, type=1
libbpf: sec 'kprobe/': found program 'trace_func_entry' at insn offset 0 (0 bytes), code size 34 insns (272 bytes)
libbpf: elf: section(4) .relkprobe/, size 16, link 24, flags 0, type=9
libbpf: elf: section(5) kretprobe/, size 88, link 0, flags 6, type=1
libbpf: sec 'kretprobe/': found program 'trace_func_exit' at insn offset 0 (0 bytes), code size 11 insns (88 bytes)
libbpf: elf: section(6) license, size 4, link 0, flags 3, type=1
libbpf: license of main.bpf.o is GPL
libbpf: elf: section(7) maps, size 20, link 0, flags 3, type=1
libbpf: elf: section(16) .BTF, size 1406, link 0, flags 0, type=1
libbpf: elf: section(18) .BTF.ext, size 460, link 0, flags 0, type=1
libbpf: elf: section(24) .symtab, size 2160, link 1, flags 0, type=2
libbpf: looking for externs among 90 symbols...
libbpf: collected 0 externs total
libbpf: elf: found 1 legacy map definitions (20 bytes) in main.bpf.o
libbpf: map 'stackdata_map' (legacy): at sec_idx 7, offset 0.
libbpf: map 87 is "stackdata_map"
libbpf: sec '.relkprobe/': collecting relocation for section(3) 'kprobe/'
libbpf: sec '.relkprobe/': relo #0: insn #20 against 'stackdata_map'
libbpf: prog 'trace_func_entry': found map 0 (stackdata_map, sec 7, off 0) for insn #20
>> Loading eBPF program
libbpf: loading kernel BTF '/usr/lib/debug/boot/vmlinux-4.18.0-25-generic': 0
libbpf: map:stackdata_map container_name:____btf_map_stackdata_map cannot be found in BTF. Missing BPF_ANNOTATE_KV_PAIR?
libbpf: map 'stackdata_map': created successfully, fd=4
libbpf: sec 'kprobe/': found 2 CO-RE relocations
libbpf: CO-RE relocating [0] struct pt_regs: found target candidate [201] struct pt_regs in [vmlinux]
libbpf: prog 'trace_func_entry': relo #0: kind <byte_off> (0), spec is [2] struct pt_regs.di (0:14 @ offset 112)
libbpf: prog 'trace_func_entry': relo #0: matching candidate #0 [201] struct pt_regs.di (0:14 @ offset 112)
libbpf: prog 'trace_func_entry': relo #0: patched insn #2 (ALU/ALU64) imm 112 -> 112
libbpf: prog 'trace_func_entry': relo #1: kind <byte_off> (0), spec is [2] struct pt_regs.si (0:13 @ offset 104)
libbpf: prog 'trace_func_entry': relo #1: matching candidate #0 [201] struct pt_regs.si (0:13 @ offset 104)
libbpf: prog 'trace_func_entry': relo #1: patched insn #9 (ALU/ALU64) imm 104 -> 104
libbpf: sec 'kretprobe/': found 1 CO-RE relocations
libbpf: prog 'trace_func_exit': relo #0: kind <byte_off> (0), spec is [2] struct pt_regs.ax (0:10 @ offset 80)
libbpf: prog 'trace_func_exit': relo #0: matching candidate #0 [201] struct pt_regs.ax (0:10 @ offset 80)
libbpf: prog 'trace_func_exit': relo #0: patched insn #2 (ALU/ALU64) imm 80 -> 80
libbpf: load bpf program failed: Invalid argument
libbpf: failed to load program 'trace_func_entry'
libbpf: failed to load object 'main.bpf.o'
bpf_object__load: -22



============  BPF Code: ============

// Compiled with:
	// clang -I /home/[...]/DATA/90_lib/libbpf/build/root/usr/include/ -target bpf -S -D __BPF_TRACING__ -D__TARGET_ARCH_x86 -Wall -O2 -emit-llvm -c -g main.bpf.c
	// llc-11 -march=bpf -filetype=obj -o main.bpf.o main.bpf.ll
// __TARGET_ARCH_x86: For x86_64 machines, too. (see bpf_tracing.h)

#include "../91_bin/vmlinux.h"

#include <bpf/bpf_core_read.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>

// #include <uapi/linux/bpf.h>  // Conflicts with vmlinux.h
/* flags for both BPF_FUNC_get_stackid and BPF_FUNC_get_stack. */
#define BPF_F_SKIP_FIELD_MASK		0xffULL     // Missing definitions in vmlinux.h
#define BPF_F_USER_STACK		(1ULL << 8)
/* flags used by BPF_FUNC_get_stackid only. */
#define BPF_F_FAST_STACK_CMP		(1ULL << 9)
#define BPF_F_REUSE_STACKID		(1ULL << 10)
/* flags used by BPF_FUNC_get_stack only. */
#define BPF_F_USER_BUILD_ID		(1ULL << 11)

char _license[] SEC("license") = "GPL";

#define MAX_STACK_RAWTP 100
struct stack_trace_t {
	int pid;
	int kern_stack_size;
	int user_stack_size;
	int user_stack_buildid_size;
	__u64 kern_stack[MAX_STACK_RAWTP];
	__u64 user_stack[MAX_STACK_RAWTP];
	struct bpf_stack_build_id user_stack_buildid[MAX_STACK_RAWTP];
};

struct bpf_map_def SEC("maps") stackdata_map = {
	.type = BPF_MAP_TYPE_PERCPU_ARRAY,
	.key_size = sizeof(__u32),
	.value_size = sizeof(struct stack_trace_t),
	.max_entries = 1,
};

SEC("kprobe/")
int trace_func_entry(struct pt_regs *ctx)
{
    u64 pid_tgid = bpf_get_current_pid_tgid();
    u32 pid = pid_tgid;

    {
        // char fmt[] = "Catched function call; PID = : %d.\n";
        // bpf_trace_printk(fmt, sizeof(fmt), pid, sizeof(pid));
    }

    int arg1;
    int arg2;

    arg1 = BPF_CORE_READ(ctx, di);
    arg2 = PT_REGS_PARM2_CORE(ctx);

    {
        // char fmt[] = "  Arg1 = : %u.\n";
        // bpf_trace_printk(fmt, sizeof(fmt), arg1, sizeof(arg1));
    }
    {
        // char fmt[] = "  Arg2 = : %u.\n";
        // bpf_trace_printk(fmt, sizeof(fmt), arg2, sizeof(arg2));
    }

    __u32 key = 0;
    struct stack_trace_t* data;
    data = bpf_map_lookup_elem(&stackdata_map, &key);
	if (!data)
		return 0;

    size_t max_len = MAX_STACK_RAWTP * sizeof(__u64);

    data->user_stack_size = bpf_get_stack(ctx, data->user_stack, max_len, BPF_F_USER_STACK);

    if(data->user_stack_size <= 0)
        return 0;
    
    {
        // char fmt[] = "  Got stack; len = : %u.\n";
        // bpf_trace_printk(fmt, sizeof(fmt), data->user_stack_size, sizeof(data->user_stack_size));
    }

    if(data->user_stack_size > MAX_STACK_RAWTP)
        return 0; // make verifier happy

    // // for(size_t i = 0; i < data->user_stack_size; ++i)
    // #pragma clang loop unroll(full)
    // for(size_t i = 0; i < 20; ++i)
    // {
    //     if(i < data->user_stack_size)
    //     {
    //         u64 stackEntry = data->user_stack[i];
    //         stackEntry += 1;

    //         char val[22];
    //         toHex(stackEntry, val, false);
    //         char fmt[] = "    : %s.\n";
    //         bpf_trace_printk(fmt, sizeof(fmt), val, sizeof(val));
    //     }
    // }

    return 0;
}


SEC("kretprobe/")
int trace_func_exit(struct pt_regs *ctx)
{
    u64 pid_tgid = bpf_get_current_pid_tgid();
    u32 pid = pid_tgid;
 
    {
        // char fmt[] = "Catched function exit; PID = : %d.\n";
        // bpf_trace_printk(fmt, sizeof(fmt), pid, sizeof(pid));
    }

    int ret;
    //bpf_probe_read_user(&key.c, sizeof(key.c), (void *)PT_REGS_PARM1(ctx));
    // arg1 = ctx->di;     // Automatic CO:RE Relocation and rewriting

    // ret = PT_REGS_RET_CORE(ctx);     // Does NOT work - Result is passed using Register eax
    ret = BPF_CORE_READ(ctx, ax);

    {
        // char fmt[] = "    ret = : %u.\n";
        // bpf_trace_printk(fmt, sizeof(fmt), ret, sizeof(ret));
    }

    return 0;
}



============ Loader code ============

// Compiled with 
	// g++ -I /home/[...]/DATA/90_lib/libbpf/build/root/usr/include/ -L../90_lib/libbpf/build/root/usr/lib64 \
	//	-l:libbpf.a \
	//	-o ebpf main.cc -Wl,--copy-dt-needed-entries /home/[...]/DATA/90_lib/libbpf/build/root/usr/lib64/libbpf.a -B static -lelf

#include <iostream>
#include <thread>
#include <chrono>
#include <unistd.h>
#include <fstream>
#include <dirent.h>

#include <linux/bpf.h>
enum bpf_stats_type {           // Should be defined in linux/bpf.h,. but is not (before Kernel 5.8)
	BPF_STATS_RUN_TIME = 0,         // used in libbpf/build/root/usr/include/bpf/bpf.h
};

#include <bpf/bpf.h>
// #include "../91_bin/vmlinux.h"
#include <bpf/libbpf.h>

#include <linux/ptrace.h>
#include <sys/resource.h>

using namespace std;

void bump_memlock_rlimit(void)
{
	struct rlimit rlim_new = {
		.rlim_cur	= RLIM_INFINITY,
		.rlim_max	= RLIM_INFINITY,
	};

	if (setrlimit(RLIMIT_MEMLOCK, &rlim_new)) {
		fprintf(stderr, "Failed to increase RLIMIT_MEMLOCK limit!\n");
		exit(1);
	}
}


int print_libbpf_log(enum libbpf_print_level lvl, const char *fmt, va_list args)
{
    return vfprintf(stderr, fmt, args);
}


int getProcIdByName(string procName)
{
    int pid = -1;

    // Open the /proc directory
    DIR *dp = opendir("/proc");
    if (dp != NULL)
    {
        // Enumerate all entries in directory until process found
        struct dirent *dirp;
        while (pid < 0 && (dirp = readdir(dp)))
        {
            // Skip non-numeric entries
            int id = atoi(dirp->d_name);
            if (id > 0)
            {
                // Read contents of virtual /proc/{pid}/cmdline file
                string cmdPath = string("/proc/") + dirp->d_name + "/cmdline";
                ifstream cmdFile(cmdPath.c_str());
                string cmdLine;
                getline(cmdFile, cmdLine);
                if (!cmdLine.empty())
                {
                    // Keep first cmdline item which contains the program path
                    size_t pos = cmdLine.find('\0');
                    if (pos != string::npos)
                        cmdLine = cmdLine.substr(0, pos);
                    // Keep program name only, removing the path
                    pos = cmdLine.rfind('/');
                    if (pos != string::npos)
                        cmdLine = cmdLine.substr(pos + 1);
                    // Compare against requested process name
                    if (procName == cmdLine)
                        pid = id;
                }
            }
        }
    }
    closedir(dp);
    return pid;
}



int main (int argc, char ** argv)
{
    bump_memlock_rlimit();
    libbpf_set_print(print_libbpf_log); /* set custom log handler */

    int prog_fd ;

    struct bpf_object_open_opts* openOpts = (struct bpf_object_open_opts*) calloc(1, sizeof(bpf_object_open_opts));
    openOpts->sz = sizeof(openOpts);
    openOpts->btf_custom_path = "./vmlinux";           // Custom BTF path - currently ignored? BTF loaded from /sys/kernel/btf/vmlinux or /usr/lib/debug/boot/vmlinux-4.18.0-25-generic
    struct bpf_object* main_bpf_obj = bpf_object__open_file("main.bpf.o", openOpts);

    if(main_bpf_obj == nullptr
    {
        cout << "Error loading bpf object: nullptr" << endl;
        return -1;
    }

    // bpf_object__set_kversion(struct bpf_object *obj, __u32 kern_version);       // For kProbes. Where to get the kernel version as u32?
    cout << ">> Loading eBPF program" << endl;
    int ret = bpf_object__load(main_bpf_obj);
    cout << "bpf_object__load: " << ret << endl;

    struct bpf_program * prog = bpf_object__find_program_by_name(main_bpf_obj, "trace_func_entry");
    struct bpf_program * retProbe = bpf_object__find_program_by_name(main_bpf_obj, "trace_func_exit");

    int pid = getProcIdByName("testApp");
    if(pid == -1)
    {
        cout << "Can not find testApp" << endl;
        return 0;
    }
    else
    {
        cout << "Found testApp with PID " << pid << endl;
    }


    cout << "Setting up Link" << endl;
    DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts);
    uprobe_opts.retprobe = false;
	struct bpf_link *uprobe_link;
    struct bpf_link *uretprobe_link;

    uprobe_link = bpf_program__attach_uprobe_opts(prog,
						      pid /* pid */,
						      "/home/[...]/DATA/Test_uProbe/testApp",
						      0x1209,		// int testApp::calc(int, int) function entry
						      &uprobe_opts);
    
    cout << "Setting up Link retprobe" << endl;

    uretprobe_link = bpf_program__attach_uprobe(retProbe, true,
                            pid,
                            "/home/[...]/DATA/Test_uProbe/testApp",
                            0x1209);


    cout << "Main loop" << endl;
    while(true)
    {
        this_thread::sleep_for(chrono::milliseconds(1000));
    }

    return 0;
}





============ testApp ============

// Compiled with g++ -o testApp testApp.cc

#include <iostream>
#include <chrono>
#include <thread>
#include <string>

using namespace std;

int calc(int a, int b)
{
    return a + b;
}

int main()
{
    int i = 0;

    while(true)
    {
        cout << calc(i, 1) << endl;
        this_thread::sleep_for(chrono::milliseconds(1000));
        ++i;
    }
    return 0;
}

^ permalink raw reply

* Re: [Buildroot] [PATCH 2/2] package/x11r7/xdriver_xf86-video-amdgpu: fix glamor dependency
From: Arnout Vandecappelle @ 2022-01-05 10:08 UTC (permalink / raw)
  To: Bernd Kuhls, buildroot
In-Reply-To: <20200410123207.3145145-2-bernd.kuhls@t-online.de>



On 10/04/2020 14:32, Bernd Kuhls wrote:
> Copy glamor dependencies from xserver_xorg-server omitting libgl/libegl
> because this package already depends on both options:
> https://git.buildroot.net/buildroot/tree/package/x11r7/xserver_xorg-server/xserver_xorg-server.mk#n192
> 
> Fixes:
> http://autobuild.buildroot.net/results/4da/4da87d30e6f5a10aafae60abce1b89ed92204a4e/
> http://autobuild.buildroot.net/results/74c/74ceb71bd48ea3a2bf6ff68aec0af76a11662f1f/
> 
> Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
> ---
>   .../xdriver_xf86-video-amdgpu/xdriver_xf86-video-amdgpu.mk  | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/package/x11r7/xdriver_xf86-video-amdgpu/xdriver_xf86-video-amdgpu.mk b/package/x11r7/xdriver_xf86-video-amdgpu/xdriver_xf86-video-amdgpu.mk
> index e7196956a3..ccb5b30d90 100644
> --- a/package/x11r7/xdriver_xf86-video-amdgpu/xdriver_xf86-video-amdgpu.mk
> +++ b/package/x11r7/xdriver_xf86-video-amdgpu/xdriver_xf86-video-amdgpu.mk
> @@ -15,6 +15,12 @@ XDRIVER_XF86_VIDEO_AMDGPU_DEPENDENCIES = \
>   	xorgproto \
>   	xserver_xorg-server
>   
> +ifeq ($(BR2_PACKAGE_LIBEPOXY),y)

  libepoxy is already select'ed in Config.in, so this condition is useless. 
Thus, this patch does exactly nothing since glamor is always enabled.

  But I guess the select could be removed from Config.in?

  I thought that maybe the issue was that libepoxy has to be added to _DEPENDS, 
but in fact, in the autobuild failures libepoxy is already built before this 
package (indirect dependency through xorg-server). So I'm not sure how this 
really should be fixed...

  BTW, the issue is still happening in autobuilders [1], just very very rarely 
(once every 4 months or so).

  Regards,
  Arnout


[1] http://autobuild.buildroot.net/?reason=xdriver_xf86-video-amdgpu%25



> +XDRIVER_XF86_VIDEO_AMDGPU_CONF_OPTS = --enable-glamor
> +else
> +XDRIVER_XF86_VIDEO_AMDGPU_CONF_OPTS = --disable-glamor
> +endif
> +
>   # xdriver_xf86-video-amdgpu requires O_CLOEXEC
>   XDRIVER_XF86_VIDEO_AMDGPU_CONF_ENV += CFLAGS="$(TARGET_CFLAGS) -D_GNU_SOURCE"
>   
> 
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply

* Re: [PATCH 5/8] PM: runtime: Add EXPORT[_GPL]_RUNTIME_DEV_PM_OPS macros
From: Jonathan Cameron @ 2022-01-05 10:07 UTC (permalink / raw)
  To: Paul Cercueil
  Cc: Rafael J . Wysocki, Ulf Hansson, Jonathan Cameron,
	Lars-Peter Clausen, Linus Walleij, Arnd Bergmann, Len Brown,
	Pavel Machek, list, linux-iio, linux-kernel, linux-mips,
	linux-mmc, linux-pm
In-Reply-To: <20220104214214.198843-6-paul@crapouillou.net>

On Tue, 4 Jan 2022 21:42:11 +0000
Paul Cercueil <paul@crapouillou.net> wrote:

> Similar to EXPORT[_GPL]_SIMPLE_DEV_PM_OPS, but for users with runtime-PM
> suspend/resume callbacks.
> 
> Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Follow up earlier comment.  I think you want pm_ptr() around all the
entries for RUNTIME_PM_OPS

Jonathan

> ---
>  include/linux/pm_runtime.h | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
> index 4af454d29281..a7f862a26c03 100644
> --- a/include/linux/pm_runtime.h
> +++ b/include/linux/pm_runtime.h
> @@ -36,6 +36,13 @@
>  			   pm_runtime_force_resume, suspend_fn, \
>  			   resume_fn, idle_fn)
>  
> +#define EXPORT_RUNTIME_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \
> +	_EXPORT_DEV_PM_OPS(name, pm_runtime_force_suspend, pm_runtime_force_resume, \
> +			   suspend_fn, resume_fn, idle_fn, "")
> +#define EXPORT_GPL_RUNTIME_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \
> +	_EXPORT_DEV_PM_OPS(name, pm_runtime_force_suspend, pm_runtime_force_resume, \
> +			   suspend_fn, resume_fn, idle_fn, "_gpl")
> +
>  #ifdef CONFIG_PM
>  extern struct workqueue_struct *pm_wq;
>  


^ permalink raw reply

* Re: [PATCH 1/4] arm64: Add Cortex-A510 CPU part definition
From: Suzuki K Poulose @ 2022-01-05 10:05 UTC (permalink / raw)
  To: Anshuman Khandual, linux-arm-kernel
  Cc: Catalin Marinas, Will Deacon, Mathieu Poirier, coresight,
	linux-doc, linux-kernel
In-Reply-To: <1641359159-22726-2-git-send-email-anshuman.khandual@arm.com>

On 05/01/2022 05:05, Anshuman Khandual wrote:
> Add the CPU Partnumbers for the new Arm designs.
> 
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Suzuki Poulose <suzuki.poulose@arm.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
> ---
>   arch/arm64/include/asm/cputype.h | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> index 19b8441aa8f2..e8fdc10395b6 100644
> --- a/arch/arm64/include/asm/cputype.h
> +++ b/arch/arm64/include/asm/cputype.h
> @@ -73,6 +73,7 @@
>   #define ARM_CPU_PART_CORTEX_A76		0xD0B
>   #define ARM_CPU_PART_NEOVERSE_N1	0xD0C
>   #define ARM_CPU_PART_CORTEX_A77		0xD0D
> +#define ARM_CPU_PART_CORTEX_A510	0xD46
>   #define ARM_CPU_PART_CORTEX_A710	0xD47
>   #define ARM_CPU_PART_NEOVERSE_N2	0xD49

Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH] common-user: Really fix i386 calls to safe_syscall_set_errno_tail
From: Philippe Mathieu-Daudé @ 2022-01-05 10:04 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
In-Reply-To: <20220105052339.677395-1-richard.henderson@linaro.org>

On 1/5/22 06:23, Richard Henderson wrote:
> Brown bag time: offset 0 from esp is the return address,
> offset 4 is the first argument.
> 
> Fixes: d7478d4229f0 ("common-user: Fix tail calls to safe_syscall_set_errno_tail")
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> 
> Ho hum.  I'm disappointed that our CI didn't catch this,
> despite cross-i386-user.  And I'm disappointed that I
> didn't run a full manual build on an i386 vm to catch
> it myself.  I plan on committing this directly.

Sorry for missing this myself too while reviewing, x86 is my weakness.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>  common-user/host/i386/safe-syscall.inc.S | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/common-user/host/i386/safe-syscall.inc.S b/common-user/host/i386/safe-syscall.inc.S
> index 9c45e56e480..db2ed098394 100644
> --- a/common-user/host/i386/safe-syscall.inc.S
> +++ b/common-user/host/i386/safe-syscall.inc.S
> @@ -120,7 +120,7 @@ safe_syscall_end:
>          pop     %ebp
>          .cfi_adjust_cfa_offset -4
>          .cfi_restore ebp
> -        mov     %eax, (%esp)
> +        mov     %eax, 4(%esp)
>          jmp     safe_syscall_set_errno_tail
>  
>          .cfi_endproc


^ permalink raw reply

* [PATCH 2/2] watchdog: mtk_wdt: mt7986: Add toprgu reset controller support
From: Sam Shih @ 2022-01-05 10:04 UTC (permalink / raw)
  To: Wim Van Sebroeck, Guenter Roeck, Matthias Brugger, Philipp Zabel,
	Rob Herring, Ryder Lee, linux-kernel, linux-watchdog,
	linux-arm-kernel, linux-mediatek, devicetree
  Cc: John Crispin, Sam Shih
In-Reply-To: <20220105100456.7126-1-sam.shih@mediatek.com>

Besides watchdog, the mt7986 toprgu module also provides software reset
functionality for various peripheral subsystems
(eg, ethernet, pcie, and connectivity)

Signed-off-by: Sam Shih <sam.shih@mediatek.com>
---
 drivers/watchdog/mtk_wdt.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index 543cf38bd04e..c6437fe1f4c0 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -10,6 +10,7 @@
  */
 
 #include <dt-bindings/reset/mt2712-resets.h>
+#include <dt-bindings/reset/mt7986-resets.h>
 #include <dt-bindings/reset/mt8183-resets.h>
 #include <dt-bindings/reset/mt8192-resets.h>
 #include <dt-bindings/reset/mt8195-resets.h>
@@ -76,6 +77,10 @@ static const struct mtk_wdt_data mt2712_data = {
 	.toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM,
 };
 
+static const struct mtk_wdt_data mt7986_data = {
+	.toprgu_sw_rst_num = MT7986_TOPRGU_SW_RST_NUM,
+};
+
 static const struct mtk_wdt_data mt8183_data = {
 	.toprgu_sw_rst_num = MT8183_TOPRGU_SW_RST_NUM,
 };
@@ -418,6 +423,7 @@ static int mtk_wdt_resume(struct device *dev)
 static const struct of_device_id mtk_wdt_dt_ids[] = {
 	{ .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data },
 	{ .compatible = "mediatek,mt6589-wdt" },
+	{ .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data },
 	{ .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data },
 	{ .compatible = "mediatek,mt8192-wdt", .data = &mt8192_data },
 	{ .compatible = "mediatek,mt8195-wdt", .data = &mt8195_data },
-- 
2.29.2


^ permalink raw reply related

* Re: [PATCH v2] FreeBSD: Upgrade to 12.3 release
From: Philippe Mathieu-Daudé @ 2022-01-05 10:02 UTC (permalink / raw)
  To: Brad Smith, qemu-devel, Thomas Huth, Wainer dos Santos Moschetta,
	Beraldo Leal, Alex Benn_e
In-Reply-To: <YdUCQLVe5JSWZByQ@humpty.home.comstyle.com>

On 1/5/22 03:28, Brad Smith wrote:
> FreeBSD: Upgrade to 12.3 release
> 
> Note, since libtasn1 was fixed in 12.3 [*], this commit re-enables GnuTLS.
> 
> [*] https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
> 
> 
> Signed-off-by: Brad Smith <brad@comstyle.com>
> Tested-by: Thomas Huth <thuth@redhat.com>
> Reviewed-by: Warner Losh <imp@bsdimp.com>
> ---
>  .gitlab-ci.d/cirrus.yml | 5 +----
>  tests/vm/freebsd        | 8 +++-----
>  2 files changed, 4 insertions(+), 9 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply

* [PATCH 1/2] dt-bindings: reset: mt7986: Add reset-controller header file
From: Sam Shih @ 2022-01-05 10:04 UTC (permalink / raw)
  To: Wim Van Sebroeck, Guenter Roeck, Matthias Brugger, Philipp Zabel,
	Rob Herring, Ryder Lee, linux-kernel, linux-watchdog,
	linux-arm-kernel, linux-mediatek, devicetree
  Cc: John Crispin, Sam Shih
In-Reply-To: <20220105100456.7126-1-sam.shih@mediatek.com>

Add infracfg, toprgu, and ethsys reset-controller header file
for MT7986 platform.

Signed-off-by: Sam Shih <sam.shih@mediatek.com>
---
 include/dt-bindings/reset/mt7986-resets.h | 55 +++++++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 include/dt-bindings/reset/mt7986-resets.h

diff --git a/include/dt-bindings/reset/mt7986-resets.h b/include/dt-bindings/reset/mt7986-resets.h
new file mode 100644
index 000000000000..af3d16c81192
--- /dev/null
+++ b/include/dt-bindings/reset/mt7986-resets.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT7986
+#define _DT_BINDINGS_RESET_CONTROLLER_MT7986
+
+/* INFRACFG resets */
+#define MT7986_INFRACFG_PEXTP_MAC_SW_RST	6
+#define MT7986_INFRACFG_SSUSB_SW_RST		7
+#define MT7986_INFRACFG_EIP97_SW_RST		8
+#define MT7986_INFRACFG_AUDIO_SW_RST		13
+#define MT7986_INFRACFG_CQ_DMA_SW_RST		14
+
+#define MT7986_INFRACFG_TRNG_SW_RST		17
+#define MT7986_INFRACFG_AP_DMA_SW_RST		32
+#define MT7986_INFRACFG_I2C_SW_RST		33
+#define MT7986_INFRACFG_NFI_SW_RST		34
+#define MT7986_INFRACFG_SPI0_SW_RST		35
+#define MT7986_INFRACFG_SPI1_SW_RST		36
+#define MT7986_INFRACFG_UART0_SW_RST		37
+#define MT7986_INFRACFG_UART1_SW_RST		38
+#define MT7986_INFRACFG_UART2_SW_RST		39
+#define MT7986_INFRACFG_AUXADC_SW_RST		43
+
+#define MT7986_INFRACFG_APXGPT_SW_RST		66
+#define MT7986_INFRACFG_PWM_SW_RST		68
+
+#define MT7986_INFRACFG_SW_RST_NUM		69
+
+/* TOPRGU resets */
+#define MT7986_TOPRGU_APMIXEDSYS_SW_RST		0
+#define MT7986_TOPRGU_SGMII0_SW_RST		1
+#define MT7986_TOPRGU_SGMII1_SW_RST		2
+#define MT7986_TOPRGU_INFRA_SW_RST		3
+#define MT7986_TOPRGU_U2PHY_SW_RST		5
+#define MT7986_TOPRGU_PCIE_SW_RST		6
+#define MT7986_TOPRGU_SSUSB_SW_RST		7
+#define MT7986_TOPRGU_ETHDMA_SW_RST		20
+#define MT7986_TOPRGU_CONSYS_SW_RST		23
+
+#define MT7986_TOPRGU_SW_RST_NUM		24
+
+/* ETHSYS Subsystem resets */
+#define MT7986_ETHSYS_FE_SW_RST			6
+#define MT7986_ETHSYS_PMTR_SW_RST		8
+#define MT7986_ETHSYS_GMAC_SW_RST		23
+#define MT7986_ETHSYS_PPE0_SW_RST		30
+#define MT7986_ETHSYS_PPE1_SW_RST		31
+
+#define MT7986_ETHSYS_SW_RST_NUM		32
+
+#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT7986 */
-- 
2.29.2


^ permalink raw reply related

* [LTP] [PATCH v4] Refactoring aio-stress.c using LTP API
From: Andrea Cervesato via ltp @ 2022-01-05 10:05 UTC (permalink / raw)
  To: ltp

Patch-set: aio-stress.c refactoring
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
 testcases/kernel/io/ltp-aiodio/aio-stress.c | 839 ++++++++++----------
 1 file changed, 402 insertions(+), 437 deletions(-)

diff --git a/testcases/kernel/io/ltp-aiodio/aio-stress.c b/testcases/kernel/io/ltp-aiodio/aio-stress.c
index 348f398db..5bb741f43 100644
--- a/testcases/kernel/io/ltp-aiodio/aio-stress.c
+++ b/testcases/kernel/io/ltp-aiodio/aio-stress.c
@@ -1,51 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (c) 2004 SuSE, Inc.  All Rights Reserved.
+ * Copyright (C) 2021 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * [Description]
  *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like.  Any license provided herein, whether implied or
- * otherwise, applies only to this software file.  Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA  94043, or:
- *
- *
- * aio-stress
- *
- * will open or create each file on the command line, and start a series
+ * Will open or create each file on the command line, and start a series
  * of aio to it.
  *
- * aio is done in a rotating loop.  first file1 gets 8 requests, then
- * file2, then file3 etc.  As each file finishes writing, it is switched
- * to reads
- *
- * io buffers are aligned in case you want to do raw io
+ * aio is done in a rotating loop. First file1.bin gets 8 requests, then
+ * file2.bin, then file3.bin etc. As each file finishes writing, it is switched
+ * to reads.
  *
- * compile with gcc -Wall -laio -lpthread -o aio-stress aio-stress.c
- *
- * run aio-stress -h to see the options
- *
- * Please mail Chris Mason (mason@suse.com) with bug reports or patches
+ * io buffers are aligned in case you want to do raw io.
  */
+
 #define _FILE_OFFSET_BITS 64
-#define PROG_VERSION "0.21"
 #define NEW_GETEVENTS
 
 #define _GNU_SOURCE
+#include "tst_test.h"
+
+#ifdef HAVE_LIBAIO
 #include <stdio.h>
 #include <errno.h>
 #include <assert.h>
@@ -60,11 +38,6 @@
 #include <sys/mman.h>
 #include <string.h>
 #include <pthread.h>
-
-#include "config.h"
-#include "tst_res_flags.h"
-
-#ifdef HAVE_LIBAIO
 #include <libaio.h>
 
 #define IO_FREE 0
@@ -83,52 +56,71 @@ enum {
 #define USE_SHM 1
 #define USE_SHMFS 2
 
-/*
- * various globals, these are effectively read only by the time the threads
- * are started
- */
-long stages = 0;
-unsigned long page_size_mask;
-int o_direct = 0;
-int o_sync = 0;
-int latency_stats = 0;
-int completion_latency_stats = 0;
-int io_iter = 8;
-int iterations = RUN_FOREVER;
-int max_io_submit = 0;
-long rec_len = 64 * 1024;
-int depth = 64;
-int num_threads = 1;
-int num_contexts = 1;
-off_t context_offset = 2 * 1024 * 1024;
-int fsync_stages = 1;
-int use_shm = 0;
-int shm_id;
-char *unaligned_buffer = NULL;
-char *aligned_buffer = NULL;
-int padded_reclen = 0;
-int stonewall = 1;
-int verify = 0;
-char *verify_buf = NULL;
-int unlink_files = 0;
+static char *str_num_files;
+static char *str_max_io_submit;
+static char *str_num_contexts;
+static char *str_context_offset;
+static char *str_file_size;
+static char *str_rec_len;
+static char *str_depth;
+static char *str_io_iter;
+static char *str_iterations;
+static char *str_o_direct;
+static char *str_o_sync;
+static char *str_stages;
+static char *str_use_shm;
+static char *str_fsync_stages;
+static char *str_latency_stats;
+static char *str_completion_latency_stats;
+static char *str_num_threads;
+static char *str_unlink_files;
+static char *str_verify;
+static char *str_stonewall;
+
+static int num_files;
+static long long file_size;
+static long stages;
+static unsigned long page_size_mask;
+static int o_direct;
+static int o_sync;
+static int latency_stats;
+static int completion_latency_stats;
+static int io_iter;
+static int iterations;
+static int max_io_submit;
+static long rec_len;
+static int depth;
+static int num_threads;
+static int num_contexts;
+static long long context_offset;
+static int fsync_stages;
+static int use_shm;
+static int shm_id;
+static char *unaligned_buffer;
+static char *aligned_buffer;
+static int padded_reclen;
+static int stonewall;
+static int verify;
+static char *verify_buf;
+static int unlink_files;
 
 struct io_unit;
 struct thread_info;
 
 /* pthread mutexes and other globals for keeping the threads in sync */
-pthread_cond_t stage_cond = PTHREAD_COND_INITIALIZER;
-pthread_mutex_t stage_mutex = PTHREAD_MUTEX_INITIALIZER;
-int threads_ending = 0;
-int threads_starting = 0;
-struct timeval global_stage_start_time;
-struct thread_info *global_thread_info;
+static pthread_cond_t stage_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t stage_mutex = PTHREAD_MUTEX_INITIALIZER;
+static int threads_ending;
+static int threads_starting;
+static struct timeval global_stage_start_time;
+static struct thread_info *global_thread_info;
 
 /*
  * latencies during io_submit are measured, these are the
  * granularities for deviations
  */
 #define DEVIATIONS 6
-int deviations[DEVIATIONS] = { 100, 250, 500, 1000, 5000, 10000 };
+static int deviations[DEVIATIONS] = { 100, 250, 500, 1000, 5000, 10000 };
 
 struct io_latency {
 	double max;
@@ -262,6 +254,7 @@ static double time_since(struct timeval *start_tv, struct timeval *stop_tv)
 {
 	double sec, usec;
 	double ret;
+
 	sec = stop_tv->tv_sec - start_tv->tv_sec;
 	usec = stop_tv->tv_usec - start_tv->tv_usec;
 	if (sec > 0 && usec < 0) {
@@ -280,6 +273,7 @@ static double time_since(struct timeval *start_tv, struct timeval *stop_tv)
 static double time_since_now(struct timeval *start_tv)
 {
 	struct timeval stop_time;
+
 	gettimeofday(&stop_time, NULL);
 	return time_since(start_tv, &stop_time);
 }
@@ -292,6 +286,7 @@ static void calc_latency(struct timeval *start_tv, struct timeval *stop_tv,
 {
 	double delta;
 	int i;
+
 	delta = time_since(start_tv, stop_tv);
 	delta = delta * 1000;
 
@@ -320,7 +315,6 @@ static void oper_list_add(struct io_oper *oper, struct io_oper **list)
 	oper->next = *list;
 	(*list)->prev->next = oper;
 	(*list)->prev = oper;
-	return;
 }
 
 static void oper_list_del(struct io_oper *oper, struct io_oper **list)
@@ -338,11 +332,16 @@ static void oper_list_del(struct io_oper *oper, struct io_oper **list)
 /* worker func to check error fields in the io unit */
 static int check_finished_io(struct io_unit *io)
 {
+	char out[4 * 1024];
+	char *ptr = out;
+	char *msg;
+	int ret;
 	int i;
-	if (io->res != io->buf_size) {
 
+	if (io->res != io->buf_size) {
 		struct stat s;
-		fstat(io->io_oper->fd, &s);
+
+		SAFE_FSTAT(io->io_oper->fd, &s);
 
 		/*
 		 * If file size is large enough for the read, then this short
@@ -351,8 +350,8 @@ static int check_finished_io(struct io_unit *io)
 		if ((io->io_oper->rw == READ || io->io_oper->rw == RREAD) &&
 		    s.st_size > (io->iocb.u.c.offset + io->res)) {
 
-			fprintf(stderr,
-				"io err %lu (%s) op %d, off %Lu size %d\n",
+			tst_res(TINFO,
+				"io err %lu (%s) op %d, off %llu size %d",
 				io->res, strerror(-io->res),
 				io->iocb.aio_lio_opcode, io->iocb.u.c.offset,
 				io->buf_size);
@@ -361,19 +360,23 @@ static int check_finished_io(struct io_unit *io)
 			return -1;
 		}
 	}
+
 	if (verify && io->io_oper->rw == READ) {
 		if (memcmp(io->buf, verify_buf, io->io_oper->reclen)) {
-			fprintf(stderr,
-				"verify error, file %s offset %Lu contents (offset:bad:good):\n",
+			tst_res(TINFO,
+				"verify error, file %s offset %llu contents (offset:bad:good):",
 				io->io_oper->file_name, io->iocb.u.c.offset);
 
 			for (i = 0; i < io->io_oper->reclen; i++) {
 				if (io->buf[i] != verify_buf[i]) {
-					fprintf(stderr, "%d:%c:%c ", i,
-						io->buf[i], verify_buf[i]);
+					ret = asprintf(&msg, "%d:%c:%c ", i, io->buf[i], verify_buf[i]);
+					if (ret < 0)
+						tst_brk(TBROK, "asprintf memory allocation error");
+					ptr += sprintf(ptr, "%s", msg);
+					free(msg);
 				}
 			}
-			fprintf(stderr, "\n");
+			tst_res(TINFO, "%s", out);
 		}
 
 	}
@@ -392,7 +395,7 @@ static int grab_iou(struct io_unit *io, struct io_oper *oper)
 	return 0;
 }
 
-char *stage_name(int rw)
+static char *stage_name(int rw)
 {
 	switch (rw) {
 	case WRITE:
@@ -422,38 +425,54 @@ static void print_time(struct io_oper *oper)
 	runtime = time_since_now(&oper->start_time);
 	mb = oper_mb_trans(oper);
 	tput = mb / runtime;
-	fprintf(stderr, "%s on %s (%.2f MB/s) %.2f MB in %.2fs\n",
+	tst_res(TINFO, "%s on %s (%.2f MB/s) %.2f MB in %.2fs",
 		stage_name(oper->rw), oper->file_name, tput, mb, runtime);
 }
 
 static void print_lat(char *str, struct io_latency *lat)
 {
+	char out[4 * 1024];
+	char *ptr = out;
+	char *msg;
 	double avg = lat->total_lat / lat->total_io;
 	int i;
 	double total_counted = 0;
-	fprintf(stderr, "%s min %.2f avg %.2f max %.2f\n\t",
-		str, lat->min, avg, lat->max);
+	int ret;
+
+	tst_res(TINFO, "%s min %.2f avg %.2f max %.2f", str, lat->min, avg, lat->max);
 
 	for (i = 0; i < DEVIATIONS; i++) {
-		fprintf(stderr, " %.0f < %d", lat->deviations[i],
-			deviations[i]);
+		ret = asprintf(&msg, " %.0f < %d", lat->deviations[i], deviations[i]);
+		if (ret < 0)
+			tst_brk(TBROK, "asprintf memory allocation error");
+		ptr += sprintf(ptr, "%s", msg);
 		total_counted += lat->deviations[i];
+		free(msg);
 	}
-	if (total_counted && lat->total_io - total_counted)
-		fprintf(stderr, " < %.0f", lat->total_io - total_counted);
-	fprintf(stderr, "\n");
+
+	if (total_counted && lat->total_io - total_counted) {
+		ret = asprintf(&msg, " < %.0f", lat->total_io - total_counted);
+		if (ret < 0)
+			tst_brk(TBROK, "asprintf memory allocation error");
+		ptr += sprintf(ptr, "%s", msg);
+		free(msg);
+	}
+
+	tst_res(TINFO, "%s", out);
 	memset(lat, 0, sizeof(*lat));
 }
 
 static void print_latency(struct thread_info *t)
 {
 	struct io_latency *lat = &t->io_submit_latency;
+
 	print_lat("latency", lat);
 }
 
 static void print_completion_latency(struct thread_info *t)
 {
 	struct io_latency *lat = &t->io_completion_latency;
+
 	print_lat("completion latency", lat);
 }
 
@@ -461,7 +480,7 @@ static void print_completion_latency(struct thread_info *t)
  * updates the fields in the io operation struct that belongs to this
  * io unit, and make the io unit reusable again
  */
-void finish_io(struct thread_info *t, struct io_unit *io, long result,
+static void finish_io(struct thread_info *t, struct io_unit *io, long result,
 	       struct timeval *tv_now)
 {
 	struct io_oper *oper = io->io_oper;
@@ -480,7 +499,7 @@ void finish_io(struct thread_info *t, struct io_unit *io, long result,
 	}
 }
 
-int read_some_events(struct thread_info *t)
+static int read_some_events(struct thread_info *t)
 {
 	struct io_unit *event_io;
 	struct io_event *event;
@@ -524,7 +543,7 @@ retry:
 		event_io = t->free_ious;
 		t->free_ious = t->free_ious->next;
 		if (grab_iou(event_io, oper)) {
-			fprintf(stderr, "io unit on free list but not free\n");
+			tst_res(TINFO, "io unit on free list but not free");
 			abort();
 		}
 		return event_io;
@@ -533,7 +552,8 @@ retry:
 	if (nr > 0)
 		goto retry;
 	else
-		fprintf(stderr, "no free ious after read_some_events\n");
+		tst_res(TINFO, "no free ious after read_some_events");
+
 	return NULL;
 }
 
@@ -545,9 +565,8 @@ static int io_oper_wait(struct thread_info *t, struct io_oper *oper)
 	struct io_event event;
 	struct io_unit *event_io;
 
-	if (oper == NULL) {
+	if (oper == NULL)
 		return 0;
-	}
 
 	if (oper->num_pending == 0)
 		goto done;
@@ -561,6 +580,7 @@ static int io_oper_wait(struct thread_info *t, struct io_oper *oper)
 	while (io_getevents(t->io_ctx, 1, &event, NULL) > 0) {
 #endif
 		struct timeval tv_now;
+
 		event_io = (struct io_unit *)((unsigned long)event.obj);
 
 		gettimeofday(&tv_now, NULL);
@@ -570,14 +590,13 @@ static int io_oper_wait(struct thread_info *t, struct io_oper *oper)
 			break;
 	}
 done:
-	if (oper->num_err) {
-		fprintf(stderr, "%u errors on oper, last %u\n",
-			oper->num_err, oper->last_err);
-	}
+	if (oper->num_err)
+		tst_res(TINFO, "%u errors on oper, last %u", oper->num_err, oper->last_err);
+
 	return 0;
 }
 
-off_t random_byte_offset(struct io_oper * oper)
+static off_t random_byte_offset(struct io_oper *oper)
 {
 	off_t num;
 	off_t rand_byte = oper->start;
@@ -603,9 +622,9 @@ off_t random_byte_offset(struct io_oper * oper)
 	num = (num + page_size_mask) & ~page_size_mask;
 	rand_byte += num;
 
-	if (rand_byte + oper->reclen > oper->end) {
+	if (rand_byte + oper->reclen > oper->end)
 		rand_byte -= oper->reclen;
-	}
+
 	return rand_byte;
 }
 
@@ -623,10 +642,8 @@ static struct io_unit *build_iocb(struct thread_info *t, struct io_oper *oper)
 	off_t rand_byte;
 
 	io = find_iou(t, oper);
-	if (!io) {
-		fprintf(stderr, "unable to find io unit\n");
-		return NULL;
-	}
+	if (!io)
+		tst_brk(TBROK, "unable to find io unit");
 
 	switch (oper->rw) {
 	case WRITE:
@@ -667,10 +684,10 @@ static int finish_oper(struct thread_info *t, struct io_oper *oper)
 
 	io_oper_wait(t, oper);
 	last_err = oper->last_err;
-	if (oper->num_pending > 0) {
-		fprintf(stderr, "oper num_pending is %d\n", oper->num_pending);
-	}
-	close(oper->fd);
+	if (oper->num_pending > 0)
+		tst_res(TINFO, "oper num_pending is %d", oper->num_pending);
+
+	SAFE_CLOSE(oper->fd);
 	free(oper);
 	return last_err;
 }
@@ -680,16 +697,12 @@ static int finish_oper(struct thread_info *t, struct io_oper *oper)
  * null on error
  */
 static struct io_oper *create_oper(int fd, int rw, off_t start, off_t end,
-				   int reclen, int depth, int iter,
+				   int reclen, int depth,
 				   char *file_name)
 {
 	struct io_oper *oper;
 
-	oper = malloc(sizeof(*oper));
-	if (!oper) {
-		fprintf(stderr, "unable to allocate io oper\n");
-		return NULL;
-	}
+	oper = SAFE_MALLOC(sizeof(*oper));
 	memset(oper, 0, sizeof(*oper));
 
 	oper->depth = depth;
@@ -709,7 +722,7 @@ static struct io_oper *create_oper(int fd, int rw, off_t start, off_t end,
  * does setup on num_ios worth of iocbs, but does not actually
  * start any io
  */
-int build_oper(struct thread_info *t, struct io_oper *oper, int num_ios,
+static int build_oper(struct thread_info *t, struct io_oper *oper, int num_ios,
 	       struct iocb **my_iocbs)
 {
 	int i;
@@ -726,9 +739,9 @@ int build_oper(struct thread_info *t, struct io_oper *oper, int num_ios,
 
 	for (i = 0; i < num_ios; i++) {
 		io = build_iocb(t, oper);
-		if (!io) {
+		if (!io)
 			return -1;
-		}
+
 		my_iocbs[i] = &io->iocb;
 	}
 	return num_ios;
@@ -743,6 +756,7 @@ static void update_iou_counters(struct iocb **my_iocbs, int nr,
 {
 	struct io_unit *io;
 	int i;
+
 	for (i = 0; i < nr; i++) {
 		io = (struct io_unit *)(my_iocbs[i]);
 		io->io_oper->num_pending++;
@@ -752,7 +766,7 @@ static void update_iou_counters(struct iocb **my_iocbs, int nr,
 }
 
 /* starts some io for a given file, returns zero if all went well */
-int run_built(struct thread_info *t, int num_ios, struct iocb **my_iocbs)
+static int run_built(struct thread_info *t, int num_ios, struct iocb **my_iocbs)
 {
 	int ret;
 	struct timeval start_time;
@@ -778,17 +792,17 @@ resubmit:
 		 */
 		if (ret > 0 || ret == -EAGAIN) {
 			int old_ret = ret;
-			if ((ret = read_some_events(t) > 0)) {
+
+			ret = read_some_events(t);
+			if (ret > 0) {
 				goto resubmit;
 			} else {
-				fprintf(stderr, "ret was %d and now is %d\n",
-					ret, old_ret);
+				tst_res(TINFO, "ret was %d and now is %d", ret, old_ret);
 				abort();
 			}
 		}
 
-		fprintf(stderr, "ret %d (%s) on io_submit\n", ret,
-			strerror(-ret));
+		tst_res(TINFO, "ret %d (%s) on io_submit", ret, strerror(-ret));
 		return -1;
 	}
 	update_iou_counters(my_iocbs, ret, &stop_time);
@@ -803,18 +817,18 @@ resubmit:
 static int restart_oper(struct io_oper *oper)
 {
 	int new_rw = 0;
+
 	if (oper->last_err)
 		return 0;
 
 	/* this switch falls through */
-	switch (oper->rw) {
-	case WRITE:
+	if (oper->rw == WRITE) {
 		if (stages & (1 << READ))
 			new_rw = READ;
-	case READ:
+	} else if (oper->rw == READ) {
 		if (!new_rw && stages & (1 << RWRITE))
 			new_rw = RWRITE;
-	case RWRITE:
+	} else if (oper->rw == RWRITE) {
 		if (!new_rw && stages & (1 << RREAD))
 			new_rw = RREAD;
 	}
@@ -840,24 +854,21 @@ static int restart_oper(struct io_oper *oper)
 static int oper_runnable(struct io_oper *oper)
 {
 	struct stat buf;
-	int ret;
 
 	/* first context is always runnable, if started_ios > 0, no need to
 	 * redo the calculations
 	 */
 	if (oper->started_ios || oper->start == 0)
 		return 1;
-	/*
-	 * only the sequential phases force delays in starting */
+
+	/* only the sequential phases force delays in starting */
 	if (oper->rw >= RWRITE)
 		return 1;
-	ret = fstat(oper->fd, &buf);
-	if (ret < 0) {
-		perror("fstat");
-		exit(1);
-	}
+
+	SAFE_FSTAT(oper->fd, &buf);
 	if (S_ISREG(buf.st_mode) && buf.st_size < oper->start)
 		return 0;
+
 	return 1;
 }
 
@@ -903,10 +914,9 @@ static int run_active_list(struct thread_info *t,
 	}
 	if (num_built) {
 		ret = run_built(t, num_built, t->iocbs);
-		if (ret < 0) {
-			fprintf(stderr, "error %d on run_built\n", ret);
-			exit(1);
-		}
+		if (ret < 0)
+			tst_brk(TBROK, "error %d on run_built", ret);
+
 		while (built_opers) {
 			oper = built_opers;
 			oper_list_del(oper, &built_opers);
@@ -917,46 +927,44 @@ static int run_active_list(struct thread_info *t,
 			}
 		}
 	}
+
 	return 0;
 }
 
-void drop_shm()
+static void drop_shm(void)
 {
 	int ret;
 	struct shmid_ds ds;
+
 	if (use_shm != USE_SHM)
 		return;
 
 	ret = shmctl(shm_id, IPC_RMID, &ds);
-	if (ret) {
-		perror("shmctl IPC_RMID");
-	}
+	if (ret)
+		tst_brk(TBROK, "shmctl IPC_RMID");
 }
 
-void aio_setup(io_context_t * io_ctx, int n)
+static void aio_setup(io_context_t *io_ctx, int n)
 {
 	int res = io_queue_init(n, io_ctx);
-	if (res != 0) {
-		fprintf(stderr, "io_queue_setup(%d) returned %d (%s)\n",
-			n, res, strerror(-res));
-		exit(3);
-	}
+
+	if (res != 0)
+		tst_brk(TBROK, "io_queue_setup(%d) returned %d (%s)", n, res, strerror(-res));
 }
 
 /*
  * allocate io operation and event arrays for a given thread
  */
-int setup_ious(struct thread_info *t,
+static int setup_ious(struct thread_info *t,
 	       int num_files, int depth, int reclen, int max_io_submit)
 {
 	int i;
 	size_t bytes = num_files * depth * sizeof(*t->ios);
 
 	t->ios = malloc(bytes);
-	if (!t->ios) {
-		fprintf(stderr, "unable to allocate io units\n");
-		return -1;
-	}
+	if (!t->ios)
+		tst_brk(TBROK, "unable to allocate io units");
+
 	memset(t->ios, 0, bytes);
 
 	for (i = 0; i < depth * num_files; i++) {
@@ -977,7 +985,7 @@ int setup_ious(struct thread_info *t,
 
 	t->iocbs = malloc(sizeof(struct iocb *) * max_io_submit);
 	if (!t->iocbs) {
-		fprintf(stderr, "unable to allocate iocbs\n");
+		tst_res(TINFO, "unable to allocate iocbs");
 		goto free_buffers;
 	}
 
@@ -985,9 +993,10 @@ int setup_ious(struct thread_info *t,
 
 	t->events = malloc(sizeof(struct io_event) * depth * num_files);
 	if (!t->events) {
-		fprintf(stderr, "unable to allocate ram for events\n");
+		tst_res(TINFO, "unable to allocate ram for events");
 		goto free_buffers;
 	}
+
 	memset(t->events, 0, num_files * sizeof(struct io_event) * depth);
 
 	t->num_global_ios = num_files * depth;
@@ -1008,8 +1017,8 @@ free_buffers:
  * and without trying to find a special place in each thread to map the
  * buffers to
  */
-int setup_shared_mem(int num_threads, int num_files, int depth,
-		     int reclen, int max_io_submit)
+static int setup_shared_mem(int num_threads, int num_files, int depth,
+		     int reclen)
 {
 	char *p = NULL;
 	size_t total_ram;
@@ -1024,17 +1033,17 @@ int setup_shared_mem(int num_threads, int num_files, int depth,
 	total_ram += page_size_mask;
 
 	if (use_shm == USE_MALLOC) {
-		p = malloc(total_ram);
+		p = SAFE_MALLOC(total_ram);
 	} else if (use_shm == USE_SHM) {
 		shm_id = shmget(IPC_PRIVATE, total_ram, IPC_CREAT | 0700);
 		if (shm_id < 0) {
-			perror("shmget");
+			tst_res(TINFO, "shmget error");
 			drop_shm();
 			goto free_buffers;
 		}
 		p = shmat(shm_id, (char *)0x50000000, 0);
 		if ((long)p == -1) {
-			perror("shmat");
+			tst_res(TINFO, "shmat error");
 			goto free_buffers;
 		}
 		/* won't really be dropped until we shmdt */
@@ -1046,22 +1055,22 @@ int setup_shared_mem(int num_threads, int num_files, int depth,
 		strcpy(mmap_name, "/dev/shm/XXXXXX");
 		fd = mkstemp(mmap_name);
 		if (fd < 0) {
-			perror("mkstemp");
+			tst_res(TINFO, "mkstemp error");
 			goto free_buffers;
 		}
-		unlink(mmap_name);
-		ftruncate(fd, total_ram);
+		SAFE_UNLINK(mmap_name);
+		SAFE_FTRUNCATE(fd, total_ram);
 		shm_id = fd;
 		p = mmap((char *)0x50000000, total_ram,
 			 PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
 
 		if (p == MAP_FAILED) {
-			perror("mmap");
+			tst_res(TINFO, "mmap error");
 			goto free_buffers;
 		}
 	}
 	if (!p) {
-		fprintf(stderr, "unable to allocate buffers\n");
+		tst_res(TINFO, "unable to allocate buffers");
 		goto free_buffers;
 	}
 	unaligned_buffer = p;
@@ -1080,7 +1089,7 @@ free_buffers:
  * runs through all the thread_info structs and calculates a combined
  * throughput
  */
-void global_thread_throughput(struct thread_info *t, char *this_stage)
+static void global_thread_throughput(struct thread_info *t, char *this_stage)
 {
 	int i;
 	double runtime = time_since_now(&global_stage_start_time);
@@ -1093,12 +1102,10 @@ void global_thread_throughput(struct thread_info *t, char *this_stage)
 			min_trans = t->stage_mb_trans;
 	}
 	if (total_mb) {
-		fprintf(stderr, "%s throughput (%.2f MB/s) ", this_stage,
-			total_mb / runtime);
-		fprintf(stderr, "%.2f MB in %.2fs", total_mb, runtime);
+		tst_res(TINFO, "%s throughput (%.2f MB/s)", this_stage, total_mb / runtime);
+		tst_res(TINFO, "%.2f MB in %.2fs", total_mb, runtime);
 		if (stonewall)
-			fprintf(stderr, " min transfer %.2fMB", min_trans);
-		fprintf(stderr, "\n");
+			tst_res(TINFO, "min transfer %.2fMB", min_trans);
 	}
 }
 
@@ -1111,7 +1118,7 @@ void global_thread_throughput(struct thread_info *t, char *this_stage)
  * various timings are printed in between the stages, along with
  * thread synchronization if there are more than one threads.
  */
-int worker(struct thread_info *t)
+static int *worker(struct thread_info *t)
 {
 	struct io_oper *oper;
 	char *this_stage = NULL;
@@ -1119,6 +1126,7 @@ int worker(struct thread_info *t)
 	int status = 0;
 	int iteration = 0;
 	int cnt;
+	int *ret;
 
 	aio_setup(&t->io_ctx, 512);
 
@@ -1176,7 +1184,7 @@ restart:
 	oper = t->finished_opers;
 	while (oper) {
 		if (fsync_stages)
-			fsync(oper->fd);
+			SAFE_FSYNC(oper->fd);
 		t->stage_mb_trans += oper_mb_trans(oper);
 		if (restart_oper(oper)) {
 			oper_list_del(oper, &t->finished_opers);
@@ -1191,8 +1199,8 @@ restart:
 
 	if (t->stage_mb_trans && t->num_files > 0) {
 		double seconds = time_since_now(&stage_time);
-		fprintf(stderr,
-			"thread %td %s totals (%.2f MB/s) %.2f MB in %.2fs\n",
+
+		tst_res(TINFO, "thread %td %s totals (%.2f MB/s) %.2f MB in %.2fs",
 			t - global_thread_info, this_stage,
 			t->stage_mb_trans / seconds, t->stage_mb_trans,
 			seconds);
@@ -1224,210 +1232,169 @@ restart:
 		status = finish_oper(t, oper);
 	}
 
-	if (t->num_global_pending) {
-		fprintf(stderr, "global num pending is %d\n",
-			t->num_global_pending);
-	}
+	if (t->num_global_pending)
+		tst_res(TINFO, "global num pending is %d", t->num_global_pending);
+
 	io_queue_release(t->io_ctx);
 
-	return status;
+	ret = SAFE_MALLOC(sizeof(int));
+	*ret = status;
+
+	return ret;
 }
 
 typedef void *(*start_routine) (void *);
-int run_workers(struct thread_info *t, int num_threads)
+static int run_workers(struct thread_info *t, int num_threads)
 {
+	void *retval;
 	int ret;
 	int i;
 
 	for (i = 0; i < num_threads; i++) {
-		ret =
-		    pthread_create(&t[i].tid, NULL, (start_routine) worker,
-				   t + i);
-		if (ret) {
-			perror("pthread_create");
-			exit(1);
-		}
+		ret = pthread_create(&t[i].tid, NULL, (start_routine) worker, t + i);
+		if (ret)
+			tst_brk(TBROK, "pthread_create: %s", tst_strerrno(ret));
 	}
+
 	for (i = 0; i < num_threads; i++) {
-		ret = pthread_join(t[i].tid, NULL);
-		if (ret) {
-			perror("pthread_join");
-			exit(1);
-		}
+		ret = pthread_join(t[i].tid, &retval);
+		if (ret)
+			tst_brk(TBROK, "pthread_join: %s", tst_strerrno(ret));
+
+		ret = *((int *) retval);
+		if (ret)
+			return ret;
 	}
+
 	return 0;
 }
 
-off_t parse_size(char *size_arg, off_t mult)
+static void setup(void)
 {
-	char c;
-	int num;
-	off_t ret;
-	c = size_arg[strlen(size_arg) - 1];
-	if (c > '9') {
-		size_arg[strlen(size_arg) - 1] = '\0';
-	}
-	num = atoi(size_arg);
-	switch (c) {
-	case 'g':
-	case 'G':
-		mult = 1024 * 1024 * 1024;
-		break;
-	case 'm':
-	case 'M':
-		mult = 1024 * 1024;
-		break;
-	case 'k':
-	case 'K':
-		mult = 1024;
-		break;
-	case 'b':
-	case 'B':
-		mult = 1;
-		break;
+	struct stat sb;
+	int maxaio;
+	int stages_i;
+
+	num_files = 1;
+	max_io_submit = 0;
+	num_contexts = 1;
+	context_offset = 2 * 1024 * 1024;
+	file_size = 1024 * 1024 * 1024;
+	rec_len = 64 * 1024;
+	depth = 64;
+	io_iter = 8;
+	iterations = RUN_FOREVER;
+	o_direct = 0;
+	o_sync = 0;
+	stages = 0;
+	use_shm = 0;
+	fsync_stages = 1;
+	latency_stats = 0;
+	completion_latency_stats = 0;
+	num_threads = 1;
+	unlink_files = 0;
+	verify = 0;
+	stonewall = 1;
+	padded_reclen = 0;
+	threads_ending = 0;
+	threads_starting = 0;
+
+	SAFE_STAT(".", &sb);
+	page_size_mask = sb.st_blksize;
+
+	SAFE_FILE_SCANF("/proc/sys/fs/aio-max-nr", "%d", &maxaio);
+	tst_res(TINFO, "Maximum AIO blocks: %d", maxaio);
+
+	if (tst_parse_int(str_num_files, &num_files, 1, INT_MAX))
+		tst_brk(TBROK, "Invalid number of files to generate '%s'", str_num_files);
+
+	if (tst_parse_int(str_max_io_submit, &max_io_submit, 0, INT_MAX))
+		tst_brk(TBROK, "Invalid number of iocbs '%s'", str_max_io_submit);
+
+	if (max_io_submit > maxaio)
+		tst_res(TCONF, "Number of async IO blocks passed the maximum (%d)", maxaio);
+
+	if (tst_parse_int(str_num_contexts, &num_contexts, 1, INT_MAX))
+		tst_brk(TBROK, "Invalid number of contexts per file '%s'", str_num_contexts);
+
+	if (tst_parse_filesize(str_context_offset, &context_offset, 1, LLONG_MAX))
+		tst_brk(TBROK, "Invalid offset between contexts '%s'", str_context_offset);
+
+	if (tst_parse_filesize(str_file_size, &file_size, 1, LLONG_MAX))
+		tst_brk(TBROK, "Invalid file size '%s'", str_file_size);
+
+	if (tst_parse_long(str_rec_len, &rec_len, 1, LONG_MAX))
+		tst_brk(TBROK, "Invalid record size '%s'", str_rec_len);
+
+	if (tst_parse_int(str_depth, &depth, 1, INT_MAX))
+		tst_brk(TBROK, "Invalid number of pending aio requests '%s'", str_depth);
+
+	if (tst_parse_int(str_io_iter, &io_iter, 1, INT_MAX))
+		tst_brk(TBROK, "Invalid number of I/O per file '%s'", str_io_iter);
+
+	if (tst_parse_int(str_iterations, &iterations, 1, INT_MAX))
+		tst_brk(TBROK, "Invalid number of total ayncs I/O '%s'", str_iterations);
+
+	if (iterations == INT_MAX)
+		iterations = RUN_FOREVER;
+
+	if (tst_parse_int(str_stages, &stages_i, 0, INT_MAX))
+		tst_brk(TBROK, "Invalid stage number '%s'", str_stages);
+
+	if (stages_i) {
+		stages |= 1 << stages_i;
+		tst_res(TINFO, "Adding stage %s", stage_name(stages_i));
+	}
+
+	if (tst_parse_int(str_num_threads, &num_threads, 1, INT_MAX))
+		tst_brk(TBROK, "Invalid number of threads '%s'", str_num_threads);
+
+	if (str_o_direct)
+		o_direct = O_DIRECT;
+
+	if (str_o_sync)
+		o_sync = O_SYNC;
+
+	if (str_use_shm) {
+		if (!strcmp(str_use_shm, "shm")) {
+			tst_res(TINFO, "using ipc shm");
+			use_shm = USE_SHM;
+		} else if (!strcmp(str_use_shm, "shmfs")) {
+			tst_res(TINFO, "using /dev/shm for buffers");
+			use_shm = USE_SHMFS;
+		}
 	}
-	ret = mult * num;
-	return ret;
-}
 
-void print_usage(void)
-{
-	printf
-	    ("usage: aio-stress [-s size] [-r size] [-a size] [-d num] [-b num]\n");
-	printf
-	    ("                  [-i num] [-t num] [-c num] [-C size] [-nxhOS ]\n");
-	printf("                  file1 [file2 ...]\n");
-	printf("\t-a size in KB at which to align buffers\n");
-	printf("\t-b max number of iocbs to give io_submit at once\n");
-	printf("\t-c number of io contexts per file\n");
-	printf("\t-C offset between contexts, default 2MB\n");
-	printf("\t-s size in MB of the test file(s), default 1024MB\n");
-	printf("\t-r record size in KB used for each io, default 64KB\n");
-	printf
-	    ("\t-d number of pending aio requests for each file, default 64\n");
-	printf("\t-i number of I/O per file sent before switching\n"
-	       "\t   to the next file, default 8\n");
-	printf("\t-I total number of ayncs I/O the program will run, "
-	       "default is run until Cntl-C\n");
-	printf("\t-O Use O_DIRECT (not available in 2.4 kernels),\n");
-	printf("\t-S Use O_SYNC for writes\n");
-	printf("\t-o add an operation to the list: write=0, read=1,\n");
-	printf("\t   random write=2, random read=3.\n");
-	printf("\t   repeat -o to specify multiple ops: -o 0 -o 1 etc.\n");
-	printf
-	    ("\t-m shm use ipc shared memory for io buffers instead of malloc\n");
-	printf("\t-m shmfs mmap a file in /dev/shm for io buffers\n");
-	printf("\t-n no fsyncs between write stage and read stage\n");
-	printf("\t-l print io_submit latencies after each stage\n");
-	printf("\t-L print io completion latencies after each stage\n");
-	printf("\t-t number of threads to run\n");
-	printf("\t-u unlink files after completion\n");
-	printf("\t-v verification of bytes written\n");
-	printf("\t-x turn off thread stonewalling\n");
-	printf("\t-h this message\n");
-	printf
-	    ("\n\t   the size options (-a -s and -r) allow modifiers -s 400{k,m,g}\n");
-	printf("\t   translate to 400KB, 400MB and 400GB\n");
-	printf("version %s\n", PROG_VERSION);
+	if (str_fsync_stages)
+		fsync_stages = 0;
+
+	if (str_latency_stats)
+		latency_stats = 1;
+
+	if (str_completion_latency_stats)
+		completion_latency_stats = 1;
+
+	if (str_unlink_files)
+		unlink_files = 1;
+
+	if (str_verify)
+		verify = 1;
+
+	if (str_stonewall)
+		stonewall = 0;
 }
 
-int main(int ac, char **av)
+static void run(void)
 {
-	int rwfd;
-	int i;
-	int j;
-	int c;
-
-	off_t file_size = 1 * 1024 * 1024 * 1024;
+	char files[num_files][265];
 	int first_stage = WRITE;
 	struct io_oper *oper;
 	int status = 0;
-	int num_files = 0;
 	int open_fds = 0;
 	struct thread_info *t;
-
-	page_size_mask = getpagesize() - 1;
-
-	while (1) {
-		c = getopt(ac, av, "a:b:c:C:m:s:r:d:i:I:o:t:lLnhOSxvu");
-		if (c < 0)
-			break;
-
-		switch (c) {
-		case 'a':
-			page_size_mask = parse_size(optarg, 1024);
-			page_size_mask--;
-			break;
-		case 'c':
-			num_contexts = atoi(optarg);
-			break;
-		case 'C':
-			context_offset = parse_size(optarg, 1024 * 1024);
-		case 'b':
-			max_io_submit = atoi(optarg);
-			break;
-		case 's':
-			file_size = parse_size(optarg, 1024 * 1024);
-			break;
-		case 'd':
-			depth = atoi(optarg);
-			break;
-		case 'r':
-			rec_len = parse_size(optarg, 1024);
-			break;
-		case 'i':
-			io_iter = atoi(optarg);
-			break;
-		case 'I':
-			iterations = atoi(optarg);
-			break;
-		case 'n':
-			fsync_stages = 0;
-			break;
-		case 'l':
-			latency_stats = 1;
-			break;
-		case 'L':
-			completion_latency_stats = 1;
-			break;
-		case 'm':
-			if (!strcmp(optarg, "shm")) {
-				fprintf(stderr, "using ipc shm\n");
-				use_shm = USE_SHM;
-			} else if (!strcmp(optarg, "shmfs")) {
-				fprintf(stderr, "using /dev/shm for buffers\n");
-				use_shm = USE_SHMFS;
-			}
-			break;
-		case 'o':
-			i = atoi(optarg);
-			stages |= 1 << i;
-			fprintf(stderr, "adding stage %s\n", stage_name(i));
-			break;
-		case 'O':
-			o_direct = O_DIRECT;
-			break;
-		case 'S':
-			o_sync = O_SYNC;
-			break;
-		case 't':
-			num_threads = atoi(optarg);
-			break;
-		case 'x':
-			stonewall = 0;
-			break;
-		case 'u':
-			unlink_files = 1;
-			break;
-		case 'v':
-			verify = 1;
-			break;
-		case 'h':
-		default:
-			print_usage();
-			exit(1);
-		}
-	}
+	int rwfd;
+	int i;
+	int j;
 
 	/*
 	 * make sure we don't try to submit more I/O than we have allocated
@@ -1435,28 +1402,15 @@ int main(int ac, char **av)
 	 */
 	if (depth < io_iter) {
 		io_iter = depth;
-		fprintf(stderr, "dropping io_iter to %d\n", io_iter);
-	}
-
-	if (optind >= ac) {
-		print_usage();
-		exit(1);
+		tst_res(TINFO, "dropping io_iter to %d", io_iter);
 	}
 
-	num_files = ac - optind;
-
 	if (num_threads > (num_files * num_contexts)) {
 		num_threads = num_files * num_contexts;
-		fprintf(stderr,
-			"dropping thread count to the number of contexts %d\n",
-			num_threads);
+		tst_res(TINFO, "Dropping thread count to the number of contexts %d", num_threads);
 	}
 
-	t = malloc(num_threads * sizeof(*t));
-	if (!t) {
-		perror("malloc");
-		exit(1);
-	}
+	t = SAFE_MALLOC(num_threads * sizeof(*t));
 	memset(t, 0, num_threads * sizeof(*t));
 	global_thread_info = t;
 
@@ -1471,100 +1425,111 @@ int main(int ac, char **av)
 	 */
 	if (max_io_submit < io_iter) {
 		io_iter = max_io_submit;
-		fprintf(stderr, "dropping io_iter to %d\n", io_iter);
+		tst_res(TINFO, "dropping io_iter to %d", io_iter);
 	}
 
 	if (!stages) {
-		stages =
-		    (1 << WRITE) | (1 << READ) | (1 << RREAD) | (1 << RWRITE);
+		stages = (1 << WRITE) | (1 << READ) | (1 << RREAD) | (1 << RWRITE);
 	} else {
 		for (i = 0; i < LAST_STAGE; i++) {
 			if (stages & (1 << i)) {
 				first_stage = i;
-				fprintf(stderr, "starting with %s\n",
-					stage_name(i));
+				tst_res(TINFO, "starting with %s", stage_name(i));
 				break;
 			}
 		}
 	}
 
-	if (file_size < num_contexts * context_offset) {
-		fprintf(stderr, "file size %ld too small for %d contexts\n",
+	if (file_size < num_contexts * context_offset)
+		tst_brk(TBROK, "file size %ld too small for %d contexts",
 			(long)file_size, num_contexts);
-		exit(1);
-	}
 
-	fprintf(stderr, "file size %ldMB, record size %ldKB, depth %d, "
-		"I/O per iteration %d\n",
+	tst_res(TINFO, "file size %ldMB, record size %ldKB, depth %d, "
+		"I/O per iteration %d",
 		(long)(file_size / (1024 * 1024)),
 		rec_len / 1024, depth, io_iter);
-	fprintf(stderr, "max io_submit %d, buffer alignment set to %luKB\n",
+	tst_res(TINFO, "max io_submit %d, buffer alignment set to %luKB",
 		max_io_submit, (page_size_mask + 1) / 1024);
-	fprintf(stderr, "threads %d files %d contexts %d context offset %ldMB "
-		"verification %s\n", num_threads, num_files, num_contexts,
+	tst_res(TINFO, "threads %d files %d contexts %d context offset %ldMB "
+		"verification %s", num_threads, num_files, num_contexts,
 		(long)(context_offset / (1024 * 1024)), verify ? "on" : "off");
+
 	/* open all the files and do any required setup for them */
-	for (i = optind; i < ac; i++) {
+	for (i = 0; i < num_files; i++) {
 		int thread_index;
+
+		snprintf(files[i], sizeof(files[i]), "file%d.bin", i);
+
 		for (j = 0; j < num_contexts; j++) {
 			thread_index = open_fds % num_threads;
 			open_fds++;
 
-			rwfd =
-			    open(av[i], O_CREAT | O_RDWR | o_direct | o_sync,
-				 0600);
-			if (rwfd == -1) {
-				fprintf(stderr,
-					"error while creating file %s: %s",
-					av[i], strerror(errno));
-				exit(1);
-			}
+			rwfd = SAFE_OPEN(files[i], O_CREAT | O_RDWR | o_direct | o_sync, 0600);
+
+			oper = create_oper(rwfd, first_stage, j * context_offset,
+				file_size - j * context_offset, rec_len,
+				depth, files[i]);
+			if (!oper)
+				tst_brk(TBROK, "error in create_oper");
 
-			oper =
-			    create_oper(rwfd, first_stage, j * context_offset,
-					file_size - j * context_offset, rec_len,
-					depth, io_iter, av[i]);
-			if (!oper) {
-				fprintf(stderr, "error in create_oper\n");
-				exit(-1);
-			}
 			oper_list_add(oper, &t[thread_index].active_opers);
 			t[thread_index].num_files++;
 		}
 	}
-	if (setup_shared_mem(num_threads, num_files * num_contexts,
-			     depth, rec_len, max_io_submit)) {
-		exit(1);
-	}
+
+	if (setup_shared_mem(num_threads, num_files * num_contexts, depth, rec_len))
+		tst_brk(TBROK, "error in setup_shared_mem");
+
 	for (i = 0; i < num_threads; i++) {
-		if (setup_ious
-		    (&t[i], t[i].num_files, depth, rec_len, max_io_submit))
-			exit(1);
+		if (setup_ious(&t[i], t[i].num_files, depth, rec_len, max_io_submit))
+			tst_brk(TBROK, "error in setup_ious");
 	}
+
 	if (num_threads > 1) {
-		printf("Running multi thread version num_threads:%d\n",
-		       num_threads);
-		run_workers(t, num_threads);
+		tst_res(TINFO, "Running multi thread version num_threads: %d", num_threads);
+		status = run_workers(t, num_threads);
 	} else {
-		printf("Running single thread version \n");
-		status = worker(t);
-	}
-	if (unlink_files) {
-		for (i = optind; i < ac; i++) {
-			printf("Cleaning up file %s \n", av[i]);
-			unlink(av[i]);
-		}
+		tst_res(TINFO, "Running single thread version");
+		status = *worker(t);
 	}
 
-	if (status) {
-		exit(1);
-	}
-	return status;
+	for (i = 0; i < num_files; i++)
+		SAFE_UNLINK(files[i]);
+
+	if (status)
+		tst_res(TFAIL, "Test did not pass");
+	else
+		tst_res(TPASS, "Test passed");
 }
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.needs_tmpdir = 1,
+	.options = (struct tst_option[]) {
+		{"f:", &str_num_files, "Number of files to generate"},
+		{"b:", &str_max_io_submit, "Max number of iocbs to give io_submit at once"},
+		{"c:", &str_num_contexts, "Number of io contexts per file"},
+		{"g:", &str_context_offset, "Offset between contexts (default 2M)"},
+		{"s:", &str_file_size, "Size in MB of the test file(s) (default 1024M)"},
+		{"r:", &str_rec_len, "Record size in KB used for each io (default 64K)"},
+		{"d:", &str_depth, "Number of pending aio requests for each file (default 64)"},
+		{"e:", &str_io_iter, "Number of I/O per file sent before switching to the next file (default 8)"},
+		{"a:", &str_iterations, "Total number of ayncs I/O the program will run, default is run until Cntl-C"},
+		{"O", &str_o_direct, "Use O_DIRECT (not available in 2.4 kernels)"},
+		{"S", &str_o_sync, "Use O_SYNC for writes"},
+		{"o:", &str_stages, "Add an operation to the list: write=0, read=1, random write=2, random read=3"},
+		{"m", &str_use_shm, "SHM use ipc shared memory for io buffers instead of malloc"},
+		{"n", &str_fsync_stages, "No fsyncs between write stage and read stage"},
+		{"l", &str_latency_stats, "Print io_submit latencies after each stage"},
+		{"L", &str_completion_latency_stats, "Print io completion latencies after each stage"},
+		{"t:", &str_num_threads, "Number of threads to run"},
+		{"u", &str_unlink_files, "Unlink files after completion"},
+		{"v", &str_verify, "Verification of bytes written"},
+		{"x", &str_stonewall, "Turn off thread stonewalling"},
+		{}
+	}
+};
 #else
-int main(void)
-{
-	fprintf(stderr, "test requires libaio and it's development packages\n");
-	return TCONF;
-}
+TST_TEST_TCONF("test requires libaio and its development packages");
 #endif
-- 
2.34.1


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.