LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: PROBLEM: monotonic clock going backwards on ppc64
From: Daniel Axtens @ 2019-02-28  6:48 UTC (permalink / raw)
  To: Jakub Drnec, linuxppc-dev
In-Reply-To: <HaC.ZfES.62bwlnvAvMP.1STMMj@seznam.cz>

Hi,

> I think I observed a potential problem, is this the correct place to report it? (CC me, not on list)

Yes

> [1.] One line summary: monotonic clock can be made to decrease on ppc64
> [2.] Full description:
> Setting the realtime clock can sometimes make the monotonic clock go back by over a hundred years.
> Decreasing the realtime clock across the y2k38 threshold is one reliable way to reproduce.
> Allegedly this can also happen just by running ntpd, I have not managed to reproduce that other
> than booting with rtc at >2038 and then running ntp.
> When this happens, anything with timers (e.g. openjdk) breaks rather badly.

I can confirm this on a physical 64bit book3e system and powerpc/next
with the provided reproducer.

> [X.] Other notes, patches, fixes, workarounds:
> The problem seems to be in vDSO code in arch/powerpc/kernel/vdso64/gettimeofday.S.
> (possibly because some values used in the calculation are only 32 bit?)
> Slightly silly workaround: 
> nuke the "cmpwi cr1,r3,CLOCK_MONOTONIC" in __kernel_clock_gettime
> Now it always goes through the syscall fallback which does not have the same problem.

I'll look at the asm but I'm no expert here so we might need to defer to
someone with real expertise. Falling back to the syscall sadly ruins
the performance gain of having a vDSO.

Regards,
Daniel


^ permalink raw reply

* [PATCH] ASoC: cs42xx8: Remove S32_LE in format list
From: S.j. Wang @ 2019-02-28  5:56 UTC (permalink / raw)
  To: timur@kernel.org, nicoleotsuka@gmail.com, Xiubo.Lee@gmail.com,
	festevam@gmail.com, broonie@kernel.org,
	alsa-devel@alsa-project.org
  Cc: linuxppc-dev@lists.ozlabs.org

cs42xx8 is a 24-bit A/D and 24-bit D/A device, so the S32_LE
should not be in the supported format list.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
 sound/soc/codecs/cs42xx8.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c
index ebb9e0cf8364..271972337d23 100644
--- a/sound/soc/codecs/cs42xx8.c
+++ b/sound/soc/codecs/cs42xx8.c
@@ -32,8 +32,7 @@
 
 #define CS42XX8_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | \
 			 SNDRV_PCM_FMTBIT_S20_3LE | \
-			 SNDRV_PCM_FMTBIT_S24_LE | \
-			 SNDRV_PCM_FMTBIT_S32_LE)
+			 SNDRV_PCM_FMTBIT_S24_LE)
 
 /* codec private data */
 struct cs42xx8_priv {
-- 
1.9.1


^ permalink raw reply related

* Re: [PATCH] powernv: powercap: Add hard minimum powercap
From: Shilpasri G Bhat @ 2019-02-28  5:55 UTC (permalink / raw)
  To: Daniel Axtens, mpe; +Cc: ego, linuxppc-dev, linux-kernel
In-Reply-To: <871s3s34jb.fsf@dja-thinkpad.axtens.net>

Hi,

On 02/28/2019 10:14 AM, Daniel Axtens wrote:
> Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> writes:
> 
>> In POWER9, OCC(On-Chip-Controller) provides for hard and soft system
>> powercapping range. The hard powercap range is guaranteed while soft
>> powercap may or may not be asserted due to various power-thermal
>> reasons based on system configuration and workloads. This patch adds
>> a sysfs file to export the hard minimum powercap limit to allow the
>> user to set the appropriate powercap value that can be managed by the
>> system.
> 
> Maybe it's common terminology and I'm just not aware of it, but what do
> you mean by "asserted"? It doesn't appear elsewhere in the documentation
> you're patching, and it's not a use of assert that I'm familiar with...
> 
> Regards,
> Daniel
> 

I meant to say powercap will not be assured in the soft powercap range, i.e,
system may or may not be throttled of CPU frequency to remain within the powercap.

I can reword the document and commit message.

Thanks and Regards,
Shilpa

>>
>> Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
>> ---
>>  .../ABI/testing/sysfs-firmware-opal-powercap       | 10 ++++
>>  arch/powerpc/platforms/powernv/opal-powercap.c     | 66 +++++++++-------------
>>  2 files changed, 37 insertions(+), 39 deletions(-)
>>
>> diff --git a/Documentation/ABI/testing/sysfs-firmware-opal-powercap b/Documentation/ABI/testing/sysfs-firmware-opal-powercap
>> index c9b66ec..65db4c1 100644
>> --- a/Documentation/ABI/testing/sysfs-firmware-opal-powercap
>> +++ b/Documentation/ABI/testing/sysfs-firmware-opal-powercap
>> @@ -29,3 +29,13 @@ Description:	System powercap directory and attributes applicable for
>>  		  creates a request for setting a new-powercap. The
>>  		  powercap requested must be between powercap-min
>>  		  and powercap-max.
>> +
>> +What:		/sys/firmware/opal/powercap/system-powercap/powercap-hard-min
>> +Date:		Feb 2019
>> +Contact:	Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
>> +Description:	Hard minimum powercap
>> +
>> +		This file provides the hard minimum powercap limit in
>> +		Watts. The powercap value above hard minimum is always
>> +		guaranteed to be asserted and the powercap value below
>> +		the hard minimum limit may or may not be guaranteed.
>> diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c b/arch/powerpc/platforms/powernv/opal-powercap.c
>> index d90ee4f..38408e7 100644
>> --- a/arch/powerpc/platforms/powernv/opal-powercap.c
>> +++ b/arch/powerpc/platforms/powernv/opal-powercap.c
>> @@ -139,10 +139,24 @@ static void powercap_add_attr(int handle, const char *name,
>>  	attr->handle = handle;
>>  	sysfs_attr_init(&attr->attr.attr);
>>  	attr->attr.attr.name = name;
>> -	attr->attr.attr.mode = 0444;
>> +
>> +	if (!strncmp(name, "powercap-current", strlen(name))) {
>> +		attr->attr.attr.mode = 0664;
>> +		attr->attr.store = powercap_store;
>> +	} else {
>> +		attr->attr.attr.mode = 0444;
>> +	}
>> +
>>  	attr->attr.show = powercap_show;
>>  }
>>  
>> +static const char * const powercap_strs[] = {
>> +	"powercap-max",
>> +	"powercap-min",
>> +	"powercap-current",
>> +	"powercap-hard-min",
>> +};
>> +
>>  void __init opal_powercap_init(void)
>>  {
>>  	struct device_node *powercap, *node;
>> @@ -167,60 +181,34 @@ void __init opal_powercap_init(void)
>>  
>>  	i = 0;
>>  	for_each_child_of_node(powercap, node) {
>> -		u32 cur, min, max;
>> -		int j = 0;
>> -		bool has_cur = false, has_min = false, has_max = false;
>> +		u32 id;
>> +		int j, count = 0;
>>  
>> -		if (!of_property_read_u32(node, "powercap-min", &min)) {
>> -			j++;
>> -			has_min = true;
>> -		}
>> -
>> -		if (!of_property_read_u32(node, "powercap-max", &max)) {
>> -			j++;
>> -			has_max = true;
>> -		}
>> +		for (j = 0; j < ARRAY_SIZE(powercap_strs); j++)
>> +			if (!of_property_read_u32(node, powercap_strs[j], &id))
>> +				count++;
>>  
>> -		if (!of_property_read_u32(node, "powercap-current", &cur)) {
>> -			j++;
>> -			has_cur = true;
>> -		}
>> -
>> -		pcaps[i].pattrs = kcalloc(j, sizeof(struct powercap_attr),
>> +		pcaps[i].pattrs = kcalloc(count, sizeof(struct powercap_attr),
>>  					  GFP_KERNEL);
>>  		if (!pcaps[i].pattrs)
>>  			goto out_pcaps_pattrs;
>>  
>> -		pcaps[i].pg.attrs = kcalloc(j + 1, sizeof(struct attribute *),
>> +		pcaps[i].pg.attrs = kcalloc(count + 1,
>> +					    sizeof(struct attribute *),
>>  					    GFP_KERNEL);
>>  		if (!pcaps[i].pg.attrs) {
>>  			kfree(pcaps[i].pattrs);
>>  			goto out_pcaps_pattrs;
>>  		}
>>  
>> -		j = 0;
>>  		pcaps[i].pg.name = kasprintf(GFP_KERNEL, "%pOFn", node);
>> -		if (has_min) {
>> -			powercap_add_attr(min, "powercap-min",
>> -					  &pcaps[i].pattrs[j]);
>> -			pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr;
>> -			j++;
>> -		}
>> -
>> -		if (has_max) {
>> -			powercap_add_attr(max, "powercap-max",
>> -					  &pcaps[i].pattrs[j]);
>> -			pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr;
>> -			j++;
>> -		}
>> +		for (j = 0; j < ARRAY_SIZE(powercap_strs); j++) {
>> +			if (of_property_read_u32(node, powercap_strs[j], &id))
>> +				continue;
>>  
>> -		if (has_cur) {
>> -			powercap_add_attr(cur, "powercap-current",
>> +			powercap_add_attr(id, powercap_strs[j],
>>  					  &pcaps[i].pattrs[j]);
>> -			pcaps[i].pattrs[j].attr.attr.mode |= 0220;
>> -			pcaps[i].pattrs[j].attr.store = powercap_store;
>>  			pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr;
>> -			j++;
>>  		}
>>  
>>  		if (sysfs_create_group(powercap_kobj, &pcaps[i].pg)) {
>> -- 
>> 1.8.3.1
> 


^ permalink raw reply

* Re: [PATCH 00/18] Add FADump support on PowerNV platform
From: Hari Bathini @ 2019-02-28  5:24 UTC (permalink / raw)
  To: Nicholas Piggin, Ananth N Mavinakayanahalli, Vasant Hegde,
	linuxppc-dev, Mahesh J Salgaonkar, Michael Ellerman,
	Stewart Smith
In-Reply-To: <1551240037.jlygjm8fzm.astroid@bobo.none>

Hi Nick,


On 27/02/19 9:48 AM, Nicholas Piggin wrote:
> Hari Bathini's on February 22, 2019 3:35 am:
>> Firmware-Assisted Dump (FADump) is currently supported only on pseries
>> platform. This patch series adds support for powernv platform too.
>>
>> The first and third patches refactor the FADump code to make use of common
>> code across multiple platforms. The fifth patch adds basic FADump support
>> for powernv platform. Patches seven & eight honour reserved-ranges DT node
>> while reserving/releasing memory used by FADump. The next patch processes
>> CPU state data provided by firmware to create and append core notes to the
>> ELF core file. The tenth patch adds support for preserving crash data for
>> subsequent boots (useful in cases like petitboot). Patch twelve provides
>> support to export opalcore. This is to make debugging of failures in OPAL
>> code easier. The subsequent patch ensures vmcore processing is skipped
>> when only OPAL core is exported by f/w. The next patch provides option to
>> release the kernel memory used to export opalcore. Patch seventeen adds
>> backup area (an area populated before crash and used in the capture kernel
>> to setup vmcore file robustly) support on PowerNV platform. The remaining
>> patches update Firmware-Assisted Dump documentation appropriately.
>>
>> Note that the quantam of increase in robustness due to patch seventeen may
>> not be worth breaking backward compatibility for older kernel versions.
>> Would like to hear thoughts from others on it.
>>
>> The patch series is tested with the latest firmware plus the below skiboot
>> changes for MPIPL support:
>>
>>      https://patchwork.ozlabs.org/project/skiboot/list/?series=78497
>>      ("MPIPL support")
>>
>> ---
>>
>> Hari Bathini (18):
>>        powerpc/fadump: move internal fadump code to a new file
>>        powerpc/fadump: Improve fadump documentation
>>        pseries/fadump: move out platform specific support from generic code
>>        powerpc/fadump: use FADump instead of fadump for how it is pronounced
>>        powerpc/fadump: enable fadump support on OPAL based POWER platform
>>        powerpc/fadump: Update documentation about OPAL platform support
>>        powerpc/fadump: consider reserved ranges while reserving memory
>>        powerpc/fadump: consider reserved ranges while releasing memory
>>        powernv/fadump: process architected register state data provided by firmware
>>        powernv/fadump: add support to preserve crash data on FADUMP disabled kernel
>>        powerpc/fadump: update documentation about CONFIG_PRESERVE_FA_DUMP
>>        powerpc/powernv: export /proc/opalcore for analysing opal crashes
>>        powernv/fadump: Skip processing /proc/vmcore when only OPAL core exists
>>        powernv/opalcore: provide an option to invalidate /proc/opalcore file
>>        powernv/fadump: consider f/w load area
>>        powernv/fadump: update documentation about option to release opalcore
>>        powernv/fadump: use backup area to map PIR to logical CPUs
> The need to map firmware identifiers like PIR to Linux numbering comes
> up in a few places, OPAL msglog, pdbg debugger, etc. I wonder if we
> could have Linux register its logical CPU numbers with OPAL after it
> boots. Would that help with your usage?

The logical to PIR map of crashing kernel is needed in the capture kernel
(the kernel booted after crash to save the dump) that processes the register
data provided by f/w. Not sure if the logical to PIR map would be guaranteed
to be the same for both the crashing kernel and capture kernel.

Actually, I don't see any value-add in using the logical to PIR map in processing
the register data provided by f/w. pSeries isn't doing that and has been reliable.
Intention was to get inputs from others on whether it is worth it..

>>        powerpc/fadump: Update documentation about backup area support
>>
>>
>>   Documentation/powerpc/firmware-assisted-dump.txt |  208 ++--
>>   arch/powerpc/Kconfig                             |   23
>>   arch/powerpc/include/asm/fadump.h                |  190 ---
>>   arch/powerpc/include/asm/opal-api.h              |   58 +
>>   arch/powerpc/include/asm/opal.h                  |    1
>>   arch/powerpc/kernel/Makefile                     |    6
>>   arch/powerpc/kernel/fadump.c                     | 1199 ++++++++--------------
>>   arch/powerpc/kernel/fadump_internal.c            |  297 +++++
>>   arch/powerpc/kernel/fadump_internal.h            |  250 +++++
> I don't have much knowledge of fadump code, so I'll nitpick instead :P
>
> Why are you calling it fadump_internal, what's internal about it? You
> have the framework for the ops table etc here, which makes the platform
> code have to #include "../kernel/fadump_internal.h", and suggests it's
> not so internal. Seems like it would be fine just to go in
> include/asm/fadump.h and kernel fadump.c?

Intention was to use that file to put common code used by platform specific code
on both pSeries & PowerNV. How about fadump_common instead of fadump_internal
to put that in perspective?

>
>>   arch/powerpc/kernel/prom.c                       |    4
>>   arch/powerpc/platforms/powernv/Makefile          |    3
>>   arch/powerpc/platforms/powernv/opal-core.c       |  602 +++++++++++
>>   arch/powerpc/platforms/powernv/opal-fadump.c     |  670 ++++++++++++
>>   arch/powerpc/platforms/powernv/opal-fadump.h     |  116 ++
>>   arch/powerpc/platforms/powernv/opal-wrappers.S   |    1
>>   arch/powerpc/platforms/pseries/Makefile          |    1
>>   arch/powerpc/platforms/pseries/pseries_fadump.c  |  535 ++++++++++
>>   arch/powerpc/platforms/pseries/pseries_fadump.h  |   96 ++
> These hopefully could just be called pseries/fadump.[ch]? Or maybe
> rtas-fadump if you want to be like powernv.

I was trying to mimic the naming convention of other files in
dir arch/powerpc/platforms/pseries. Fine with rtas-fadump as well..

Thanks
Hari


^ permalink raw reply

* Re: [PATCH 4/5] ocxl: Remove superfluous 'extern' from headers
From: Andrew Donnellan @ 2019-02-28  5:05 UTC (permalink / raw)
  To: Alastair D'Silva, alastair
  Cc: Frederic Barrat, Greg Kroah-Hartman, linuxppc-dev, linux-kernel,
	Arnd Bergmann
In-Reply-To: <20190227045741.21412-5-alastair@au1.ibm.com>

On 27/2/19 3:57 pm, Alastair D'Silva wrote:
> From: Alastair D'Silva <alastair@d-silva.org>
> 
> The 'extern' keyword adds no value here.
> 
> Signed-off-by: Alastair D'Silva <alastair@d-silva.org>

Acked-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>


> ---
>   drivers/misc/ocxl/ocxl_internal.h | 54 +++++++++++++++----------------
>   include/misc/ocxl.h               | 36 ++++++++++-----------
>   2 files changed, 44 insertions(+), 46 deletions(-)
> 
> diff --git a/drivers/misc/ocxl/ocxl_internal.h b/drivers/misc/ocxl/ocxl_internal.h
> index a32f2151029f..321b29e77f45 100644
> --- a/drivers/misc/ocxl/ocxl_internal.h
> +++ b/drivers/misc/ocxl/ocxl_internal.h
> @@ -16,7 +16,6 @@
>   
>   extern struct pci_driver ocxl_pci_driver;
>   
> -
>   struct ocxl_fn {
>   	struct device dev;
>   	int bar_used[3];
> @@ -92,41 +91,40 @@ struct ocxl_process_element {
>   	__be32 software_state;
>   };
>   
> +struct ocxl_afu *ocxl_afu_get(struct ocxl_afu *afu);
> +void ocxl_afu_put(struct ocxl_afu *afu);
>   
> -extern struct ocxl_afu *ocxl_afu_get(struct ocxl_afu *afu);
> -extern void ocxl_afu_put(struct ocxl_afu *afu);
> -
> -extern int ocxl_create_cdev(struct ocxl_afu *afu);
> -extern void ocxl_destroy_cdev(struct ocxl_afu *afu);
> -extern int ocxl_register_afu(struct ocxl_afu *afu);
> -extern void ocxl_unregister_afu(struct ocxl_afu *afu);
> +int ocxl_create_cdev(struct ocxl_afu *afu);
> +void ocxl_destroy_cdev(struct ocxl_afu *afu);
> +int ocxl_register_afu(struct ocxl_afu *afu);
> +void ocxl_unregister_afu(struct ocxl_afu *afu);
>   
> -extern int ocxl_file_init(void);
> -extern void ocxl_file_exit(void);
> +int ocxl_file_init(void);
> +void ocxl_file_exit(void);
>   
> -extern int ocxl_pasid_afu_alloc(struct ocxl_fn *fn, u32 size);
> -extern void ocxl_pasid_afu_free(struct ocxl_fn *fn, u32 start, u32 size);
> -extern int ocxl_actag_afu_alloc(struct ocxl_fn *fn, u32 size);
> -extern void ocxl_actag_afu_free(struct ocxl_fn *fn, u32 start, u32 size);
> +int ocxl_pasid_afu_alloc(struct ocxl_fn *fn, u32 size);
> +void ocxl_pasid_afu_free(struct ocxl_fn *fn, u32 start, u32 size);
> +int ocxl_actag_afu_alloc(struct ocxl_fn *fn, u32 size);
> +void ocxl_actag_afu_free(struct ocxl_fn *fn, u32 start, u32 size);
>   
> -extern struct ocxl_context *ocxl_context_alloc(void);
> -extern int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
> +struct ocxl_context *ocxl_context_alloc(void);
> +int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu,
>   			struct address_space *mapping);
> -extern int ocxl_context_attach(struct ocxl_context *ctx, u64 amr);
> -extern int ocxl_context_mmap(struct ocxl_context *ctx,
> +int ocxl_context_attach(struct ocxl_context *ctx, u64 amr);
> +int ocxl_context_mmap(struct ocxl_context *ctx,
>   			struct vm_area_struct *vma);
> -extern int ocxl_context_detach(struct ocxl_context *ctx);
> -extern void ocxl_context_detach_all(struct ocxl_afu *afu);
> -extern void ocxl_context_free(struct ocxl_context *ctx);
> +int ocxl_context_detach(struct ocxl_context *ctx);
> +void ocxl_context_detach_all(struct ocxl_afu *afu);
> +void ocxl_context_free(struct ocxl_context *ctx);
>   
> -extern int ocxl_sysfs_add_afu(struct ocxl_afu *afu);
> -extern void ocxl_sysfs_remove_afu(struct ocxl_afu *afu);
> +int ocxl_sysfs_add_afu(struct ocxl_afu *afu);
> +void ocxl_sysfs_remove_afu(struct ocxl_afu *afu);
>   
> -extern int ocxl_afu_irq_alloc(struct ocxl_context *ctx, u64 *irq_offset);
> -extern int ocxl_afu_irq_free(struct ocxl_context *ctx, u64 irq_offset);
> -extern void ocxl_afu_irq_free_all(struct ocxl_context *ctx);
> -extern int ocxl_afu_irq_set_fd(struct ocxl_context *ctx, u64 irq_offset,
> +int ocxl_afu_irq_alloc(struct ocxl_context *ctx, u64 *irq_offset);
> +int ocxl_afu_irq_free(struct ocxl_context *ctx, u64 irq_offset);
> +void ocxl_afu_irq_free_all(struct ocxl_context *ctx);
> +int ocxl_afu_irq_set_fd(struct ocxl_context *ctx, u64 irq_offset,
>   			int eventfd);
> -extern u64 ocxl_afu_irq_get_addr(struct ocxl_context *ctx, u64 irq_offset);
> +u64 ocxl_afu_irq_get_addr(struct ocxl_context *ctx, u64 irq_offset);
>   
>   #endif /* _OCXL_INTERNAL_H_ */
> diff --git a/include/misc/ocxl.h b/include/misc/ocxl.h
> index 9ff6ddc28e22..4544573cc93c 100644
> --- a/include/misc/ocxl.h
> +++ b/include/misc/ocxl.h
> @@ -53,7 +53,7 @@ struct ocxl_fn_config {
>    * Read the configuration space of a function and fill in a
>    * ocxl_fn_config structure with all the function details
>    */
> -extern int ocxl_config_read_function(struct pci_dev *dev,
> +int ocxl_config_read_function(struct pci_dev *dev,
>   				struct ocxl_fn_config *fn);
>   
>   /*
> @@ -62,14 +62,14 @@ extern int ocxl_config_read_function(struct pci_dev *dev,
>    * AFU indexes can be sparse, so a driver should check all indexes up
>    * to the maximum found in the function description
>    */
> -extern int ocxl_config_check_afu_index(struct pci_dev *dev,
> +int ocxl_config_check_afu_index(struct pci_dev *dev,
>   				struct ocxl_fn_config *fn, int afu_idx);
>   
>   /*
>    * Read the configuration space of a function for the AFU specified by
>    * the index 'afu_idx'. Fills in a ocxl_afu_config structure
>    */
> -extern int ocxl_config_read_afu(struct pci_dev *dev,
> +int ocxl_config_read_afu(struct pci_dev *dev,
>   				struct ocxl_fn_config *fn,
>   				struct ocxl_afu_config *afu,
>   				u8 afu_idx);
> @@ -77,7 +77,7 @@ extern int ocxl_config_read_afu(struct pci_dev *dev,
>   /*
>    * Get the max PASID value that can be used by the function
>    */
> -extern int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count);
> +int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count);
>   
>   /*
>    * Tell an AFU, by writing in the configuration space, the PASIDs that
> @@ -87,7 +87,7 @@ extern int ocxl_config_get_pasid_info(struct pci_dev *dev, int *count);
>    * 'afu_control_offset' is the offset of the AFU control DVSEC which
>    * can be found in the function configuration
>    */
> -extern void ocxl_config_set_afu_pasid(struct pci_dev *dev,
> +void ocxl_config_set_afu_pasid(struct pci_dev *dev,
>   				int afu_control_offset,
>   				int pasid_base, u32 pasid_count_log);
>   
> @@ -98,7 +98,7 @@ extern void ocxl_config_set_afu_pasid(struct pci_dev *dev,
>    * 'supported' is the total number of actags desired by all the AFUs
>    *             of the function.
>    */
> -extern int ocxl_config_get_actag_info(struct pci_dev *dev,
> +int ocxl_config_get_actag_info(struct pci_dev *dev,
>   				u16 *base, u16 *enabled, u16 *supported);
>   
>   /*
> @@ -108,7 +108,7 @@ extern int ocxl_config_get_actag_info(struct pci_dev *dev,
>    * 'func_offset' is the offset of the Function DVSEC that can found in
>    * the function configuration
>    */
> -extern void ocxl_config_set_actag(struct pci_dev *dev, int func_offset,
> +void ocxl_config_set_actag(struct pci_dev *dev, int func_offset,
>   				u32 actag_base, u32 actag_count);
>   
>   /*
> @@ -118,7 +118,7 @@ extern void ocxl_config_set_actag(struct pci_dev *dev, int func_offset,
>    * 'afu_control_offset' is the offset of the AFU control DVSEC for the
>    * desired AFU. It can be found in the AFU configuration
>    */
> -extern void ocxl_config_set_afu_actag(struct pci_dev *dev,
> +void ocxl_config_set_afu_actag(struct pci_dev *dev,
>   				int afu_control_offset,
>   				int actag_base, int actag_count);
>   
> @@ -128,7 +128,7 @@ extern void ocxl_config_set_afu_actag(struct pci_dev *dev,
>    * 'afu_control_offset' is the offset of the AFU control DVSEC for the
>    * desired AFU. It can be found in the AFU configuration
>    */
> -extern void ocxl_config_set_afu_state(struct pci_dev *dev,
> +void ocxl_config_set_afu_state(struct pci_dev *dev,
>   				int afu_control_offset, int enable);
>   
>   /*
> @@ -139,7 +139,7 @@ extern void ocxl_config_set_afu_state(struct pci_dev *dev,
>    * between the host and device, and set the Transaction Layer on both
>    * accordingly.
>    */
> -extern int ocxl_config_set_TL(struct pci_dev *dev, int tl_dvsec);
> +int ocxl_config_set_TL(struct pci_dev *dev, int tl_dvsec);
>   
>   /*
>    * Request an AFU to terminate a PASID.
> @@ -152,7 +152,7 @@ extern int ocxl_config_set_TL(struct pci_dev *dev, int tl_dvsec);
>    * 'afu_control_offset' is the offset of the AFU control DVSEC for the
>    * desired AFU. It can be found in the AFU configuration
>    */
> -extern int ocxl_config_terminate_pasid(struct pci_dev *dev,
> +int ocxl_config_terminate_pasid(struct pci_dev *dev,
>   				int afu_control_offset, int pasid);
>   
>   /*
> @@ -165,13 +165,13 @@ extern int ocxl_config_terminate_pasid(struct pci_dev *dev,
>    * Returns a 'link handle' that should be used for further calls for
>    * the link
>    */
> -extern int ocxl_link_setup(struct pci_dev *dev, int PE_mask,
> +int ocxl_link_setup(struct pci_dev *dev, int PE_mask,
>   			void **link_handle);
>   
>   /*
>    * Remove the association between the function and its link.
>    */
> -extern void ocxl_link_release(struct pci_dev *dev, void *link_handle);
> +void ocxl_link_release(struct pci_dev *dev, void *link_handle);
>   
>   /*
>    * Add a Process Element to the Shared Process Area for a link.
> @@ -183,7 +183,7 @@ extern void ocxl_link_release(struct pci_dev *dev, void *link_handle);
>    * 'xsl_err_data' is an argument passed to the above callback, if
>    * defined
>    */
> -extern int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr,
> +int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr,
>   		u64 amr, struct mm_struct *mm,
>   		void (*xsl_err_cb)(void *data, u64 addr, u64 dsisr),
>   		void *xsl_err_data);
> @@ -195,12 +195,12 @@ extern int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr,
>    * pasid: the PASID for the AFU context
>    * tid: the new thread id for the process element
>    */
> -extern int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid);
> +int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid);
>   
>   /*
>    * Remove a Process Element from the Shared Process Area for a link
>    */
> -extern int ocxl_link_remove_pe(void *link_handle, int pasid);
> +int ocxl_link_remove_pe(void *link_handle, int pasid);
>   
>   /*
>    * Allocate an AFU interrupt associated to the link.
> @@ -212,12 +212,12 @@ extern int ocxl_link_remove_pe(void *link_handle, int pasid);
>    * interrupt. It is an MMIO address which needs to be remapped (one
>    * page).
>    */
> -extern int ocxl_link_irq_alloc(void *link_handle, int *hw_irq,
> +int ocxl_link_irq_alloc(void *link_handle, int *hw_irq,
>   			u64 *obj_handle);
>   
>   /*
>    * Free a previously allocated AFU interrupt
>    */
> -extern void ocxl_link_free_irq(void *link_handle, int hw_irq);
> +void ocxl_link_free_irq(void *link_handle, int hw_irq);
>   
>   #endif /* _MISC_OCXL_H_ */
> 

-- 
Andrew Donnellan              OzLabs, ADL Canberra
andrew.donnellan@au1.ibm.com  IBM Australia Limited


^ permalink raw reply

* Re: [PATCH 3/5] ocxl: read_pasid never returns an error, so make it void
From: Andrew Donnellan @ 2019-02-28  5:03 UTC (permalink / raw)
  To: Alastair D'Silva, alastair
  Cc: Arnd Bergmann, Greg Kroah-Hartman, Greg Kurz, linux-kernel,
	Frederic Barrat, linuxppc-dev
In-Reply-To: <20190227045741.21412-4-alastair@au1.ibm.com>

On 27/2/19 3:57 pm, Alastair D'Silva wrote:
> From: Alastair D'Silva <alastair@d-silva.org>
> 
> No need for a return value in read_pasid as it only returns 0.
> 
> Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
> Reviewed-by: Greg Kurz <groug@kaod.org>

Acked-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>

> ---
>   drivers/misc/ocxl/config.c | 9 ++-------
>   1 file changed, 2 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c
> index 0ee7856b033d..026ac2ac4f9c 100644
> --- a/drivers/misc/ocxl/config.c
> +++ b/drivers/misc/ocxl/config.c
> @@ -68,7 +68,7 @@ static int find_dvsec_afu_ctrl(struct pci_dev *dev, u8 afu_idx)
>   	return 0;
>   }
>   
> -static int read_pasid(struct pci_dev *dev, struct ocxl_fn_config *fn)
> +static void read_pasid(struct pci_dev *dev, struct ocxl_fn_config *fn)
>   {
>   	u16 val;
>   	int pos;
> @@ -89,7 +89,6 @@ static int read_pasid(struct pci_dev *dev, struct ocxl_fn_config *fn)
>   out:
>   	dev_dbg(&dev->dev, "PASID capability:\n");
>   	dev_dbg(&dev->dev, "  Max PASID log = %d\n", fn->max_pasid_log);
> -	return 0;
>   }
>   
>   static int read_dvsec_tl(struct pci_dev *dev, struct ocxl_fn_config *fn)
> @@ -205,11 +204,7 @@ int ocxl_config_read_function(struct pci_dev *dev, struct ocxl_fn_config *fn)
>   {
>   	int rc;
>   
> -	rc = read_pasid(dev, fn);
> -	if (rc) {
> -		dev_err(&dev->dev, "Invalid PASID configuration: %d\n", rc);
> -		return -ENODEV;
> -	}
> +	read_pasid(dev, fn);
>   
>   	rc = read_dvsec_tl(dev, fn);
>   	if (rc) {
> 

-- 
Andrew Donnellan              OzLabs, ADL Canberra
andrew.donnellan@au1.ibm.com  IBM Australia Limited


^ permalink raw reply

* Re: [PATCH 2/5] ocxl: Clean up printf formats
From: Andrew Donnellan @ 2019-02-28  5:02 UTC (permalink / raw)
  To: Alastair D'Silva, alastair
  Cc: Frederic Barrat, Greg Kroah-Hartman, linuxppc-dev, linux-kernel,
	Arnd Bergmann
In-Reply-To: <20190227045741.21412-3-alastair@au1.ibm.com>

On 27/2/19 3:57 pm, Alastair D'Silva wrote:
> From: Alastair D'Silva <alastair@d-silva.org>
> 
> Use %# instead of using a literal '0x'
> 
> Signed-off-by: Alastair D'Silva <alastair@d-silva.org>

Not hugely fussed either way, but today I learned about %#...

Acked-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>

> ---
>   drivers/misc/ocxl/config.c  |  6 +++---
>   drivers/misc/ocxl/context.c |  2 +-
>   drivers/misc/ocxl/trace.h   | 10 +++++-----
>   3 files changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c
> index 8f2c5d8bd2ee..0ee7856b033d 100644
> --- a/drivers/misc/ocxl/config.c
> +++ b/drivers/misc/ocxl/config.c
> @@ -178,9 +178,9 @@ static int read_dvsec_vendor(struct pci_dev *dev)
>   	pci_read_config_dword(dev, pos + OCXL_DVSEC_VENDOR_DLX_VERS, &dlx);
>   
>   	dev_dbg(&dev->dev, "Vendor specific DVSEC:\n");
> -	dev_dbg(&dev->dev, "  CFG version = 0x%x\n", cfg);
> -	dev_dbg(&dev->dev, "  TLX version = 0x%x\n", tlx);
> -	dev_dbg(&dev->dev, "  DLX version = 0x%x\n", dlx);
> +	dev_dbg(&dev->dev, "  CFG version = %#x\n", cfg);
> +	dev_dbg(&dev->dev, "  TLX version = %#x\n", tlx);
> +	dev_dbg(&dev->dev, "  DLX version = %#x\n", dlx);
>   	return 0;
>   }
>   
> diff --git a/drivers/misc/ocxl/context.c b/drivers/misc/ocxl/context.c
> index c10a940e3b38..3498a0199bde 100644
> --- a/drivers/misc/ocxl/context.c
> +++ b/drivers/misc/ocxl/context.c
> @@ -134,7 +134,7 @@ static vm_fault_t ocxl_mmap_fault(struct vm_fault *vmf)
>   	vm_fault_t ret;
>   
>   	offset = vmf->pgoff << PAGE_SHIFT;
> -	pr_debug("%s: pasid %d address 0x%lx offset 0x%llx\n", __func__,
> +	pr_debug("%s: pasid %d address %#lx offset %#llx\n", __func__,
>   		ctx->pasid, vmf->address, offset);
>   
>   	if (offset < ctx->afu->irq_base_offset)
> diff --git a/drivers/misc/ocxl/trace.h b/drivers/misc/ocxl/trace.h
> index bcb7ff330c1e..8d2f53812edd 100644
> --- a/drivers/misc/ocxl/trace.h
> +++ b/drivers/misc/ocxl/trace.h
> @@ -28,7 +28,7 @@ DECLARE_EVENT_CLASS(ocxl_context,
>   		__entry->tidr = tidr;
>   	),
>   
> -	TP_printk("linux pid=%d spa=0x%p pasid=0x%x pidr=0x%x tidr=0x%x",
> +	TP_printk("linux pid=%d spa=%p pasid=%#x pidr=%#x tidr=%#x",
>   		__entry->pid,
>   		__entry->spa,
>   		__entry->pasid,
> @@ -61,7 +61,7 @@ TRACE_EVENT(ocxl_terminate_pasid,
>   		__entry->rc = rc;
>   	),
>   
> -	TP_printk("pasid=0x%x rc=%d",
> +	TP_printk("pasid=%#x rc=%d",
>   		__entry->pasid,
>   		__entry->rc
>   	)
> @@ -87,7 +87,7 @@ DECLARE_EVENT_CLASS(ocxl_fault_handler,
>   		__entry->tfc = tfc;
>   	),
>   
> -	TP_printk("spa=%p pe=0x%llx dsisr=0x%llx dar=0x%llx tfc=0x%llx",
> +	TP_printk("spa=%p pe=%#llx dsisr=%#llx dar=%#llx tfc=%#llx",
>   		__entry->spa,
>   		__entry->pe,
>   		__entry->dsisr,
> @@ -127,7 +127,7 @@ TRACE_EVENT(ocxl_afu_irq_alloc,
>   		__entry->irq_offset = irq_offset;
>   	),
>   
> -	TP_printk("pasid=0x%x irq_id=%d virq=%u hw_irq=%d irq_offset=0x%llx",
> +	TP_printk("pasid=%#x irq_id=%d virq=%u hw_irq=%d irq_offset=0x%llx",
>   		__entry->pasid,
>   		__entry->irq_id,
>   		__entry->virq,
> @@ -150,7 +150,7 @@ TRACE_EVENT(ocxl_afu_irq_free,
>   		__entry->irq_id = irq_id;
>   	),
>   
> -	TP_printk("pasid=0x%x irq_id=%d",
> +	TP_printk("pasid=%#x irq_id=%d",
>   		__entry->pasid,
>   		__entry->irq_id
>   	)
> 

-- 
Andrew Donnellan              OzLabs, ADL Canberra
andrew.donnellan@au1.ibm.com  IBM Australia Limited


^ permalink raw reply

* Re: [PATCH 00/18] Add FADump support on PowerNV platform
From: Hari Bathini @ 2019-02-28  5:02 UTC (permalink / raw)
  To: Daniel Axtens, Ananth N Mavinakayanahalli, Michael Ellerman,
	Mahesh J Salgaonkar, Vasant Hegde, linuxppc-dev, Stewart Smith
In-Reply-To: <877edlaola.fsf@linkitivity.dja.id.au>


On 27/02/19 9:07 AM, Daniel Axtens wrote:
> Hi Hari,


Hi Daniel,


>> Firmware-Assisted Dump (FADump) is currently supported only on pseries
>> platform. This patch series adds support for powernv platform too.
>>
>> The first and third patches refactor the FADump code to make use of common
>> code across multiple platforms. The fifth patch adds basic FADump support
>> for powernv platform. Patches seven & eight honour reserved-ranges DT node
>> while reserving/releasing memory used by FADump. The next patch processes
>> CPU state data provided by firmware to create and append core notes to the
>> ELF core file. The tenth patch adds support for preserving crash data for
>> subsequent boots (useful in cases like petitboot). Patch twelve provides
>> support to export opalcore. This is to make debugging of failures in OPAL
>> code easier. The subsequent patch ensures vmcore processing is skipped
>> when only OPAL core is exported by f/w. The next patch provides option to
>> release the kernel memory used to export opalcore. Patch seventeen adds
>> backup area (an area populated before crash and used in the capture kernel
>> to setup vmcore file robustly) support on PowerNV platform. The remaining
>> patches update Firmware-Assisted Dump documentation appropriately.
>>
>> Note that the quantam of increase in robustness due to patch seventeen may
>> not be worth breaking backward compatibility for older kernel versions.
>> Would like to hear thoughts from others on it.
>>
>> The patch series is tested with the latest firmware plus the below skiboot
>> changes for MPIPL support:
>>
>>      https://patchwork.ozlabs.org/project/skiboot/list/?series=78497
>>      ("MPIPL support")
>>
> If I want to test this, is there some userspace tooling that will
> extract a fadump from a rebooted system and allow me to examine it as I
> would with a kdump (e.g. with crash)?  I did look at
> Documentation/powerpc/firmware-assisted-dump.txt but it seems to only
> cover the kernel layer.

This patches export two dump files: /proc/vmcore (kernel), /proc/opalcore (OPAL).
If you are only interested in kernel dump, then passing fadump=on to the kernel
and enabling/starting kdump-tools/kdump service, shipped with distro, would ensure
dump is captured to /var/crash dir and rebooted but please be aware that the
script would not copy /proc/opalcore to disk yet. Need to update scripts once this
changes make it upstream..

Thanks
Hari


^ permalink raw reply

* Re: [PATCH] powernv: powercap: Add hard minimum powercap
From: Daniel Axtens @ 2019-02-28  4:44 UTC (permalink / raw)
  To: Shilpasri G Bhat, mpe; +Cc: ego, linuxppc-dev, linux-kernel, Shilpasri G Bhat
In-Reply-To: <1551260002-26792-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com>

Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> writes:

> In POWER9, OCC(On-Chip-Controller) provides for hard and soft system
> powercapping range. The hard powercap range is guaranteed while soft
> powercap may or may not be asserted due to various power-thermal
> reasons based on system configuration and workloads. This patch adds
> a sysfs file to export the hard minimum powercap limit to allow the
> user to set the appropriate powercap value that can be managed by the
> system.

Maybe it's common terminology and I'm just not aware of it, but what do
you mean by "asserted"? It doesn't appear elsewhere in the documentation
you're patching, and it's not a use of assert that I'm familiar with...

Regards,
Daniel

>
> Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
> ---
>  .../ABI/testing/sysfs-firmware-opal-powercap       | 10 ++++
>  arch/powerpc/platforms/powernv/opal-powercap.c     | 66 +++++++++-------------
>  2 files changed, 37 insertions(+), 39 deletions(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-firmware-opal-powercap b/Documentation/ABI/testing/sysfs-firmware-opal-powercap
> index c9b66ec..65db4c1 100644
> --- a/Documentation/ABI/testing/sysfs-firmware-opal-powercap
> +++ b/Documentation/ABI/testing/sysfs-firmware-opal-powercap
> @@ -29,3 +29,13 @@ Description:	System powercap directory and attributes applicable for
>  		  creates a request for setting a new-powercap. The
>  		  powercap requested must be between powercap-min
>  		  and powercap-max.
> +
> +What:		/sys/firmware/opal/powercap/system-powercap/powercap-hard-min
> +Date:		Feb 2019
> +Contact:	Linux for PowerPC mailing list <linuxppc-dev@ozlabs.org>
> +Description:	Hard minimum powercap
> +
> +		This file provides the hard minimum powercap limit in
> +		Watts. The powercap value above hard minimum is always
> +		guaranteed to be asserted and the powercap value below
> +		the hard minimum limit may or may not be guaranteed.
> diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c b/arch/powerpc/platforms/powernv/opal-powercap.c
> index d90ee4f..38408e7 100644
> --- a/arch/powerpc/platforms/powernv/opal-powercap.c
> +++ b/arch/powerpc/platforms/powernv/opal-powercap.c
> @@ -139,10 +139,24 @@ static void powercap_add_attr(int handle, const char *name,
>  	attr->handle = handle;
>  	sysfs_attr_init(&attr->attr.attr);
>  	attr->attr.attr.name = name;
> -	attr->attr.attr.mode = 0444;
> +
> +	if (!strncmp(name, "powercap-current", strlen(name))) {
> +		attr->attr.attr.mode = 0664;
> +		attr->attr.store = powercap_store;
> +	} else {
> +		attr->attr.attr.mode = 0444;
> +	}
> +
>  	attr->attr.show = powercap_show;
>  }
>  
> +static const char * const powercap_strs[] = {
> +	"powercap-max",
> +	"powercap-min",
> +	"powercap-current",
> +	"powercap-hard-min",
> +};
> +
>  void __init opal_powercap_init(void)
>  {
>  	struct device_node *powercap, *node;
> @@ -167,60 +181,34 @@ void __init opal_powercap_init(void)
>  
>  	i = 0;
>  	for_each_child_of_node(powercap, node) {
> -		u32 cur, min, max;
> -		int j = 0;
> -		bool has_cur = false, has_min = false, has_max = false;
> +		u32 id;
> +		int j, count = 0;
>  
> -		if (!of_property_read_u32(node, "powercap-min", &min)) {
> -			j++;
> -			has_min = true;
> -		}
> -
> -		if (!of_property_read_u32(node, "powercap-max", &max)) {
> -			j++;
> -			has_max = true;
> -		}
> +		for (j = 0; j < ARRAY_SIZE(powercap_strs); j++)
> +			if (!of_property_read_u32(node, powercap_strs[j], &id))
> +				count++;
>  
> -		if (!of_property_read_u32(node, "powercap-current", &cur)) {
> -			j++;
> -			has_cur = true;
> -		}
> -
> -		pcaps[i].pattrs = kcalloc(j, sizeof(struct powercap_attr),
> +		pcaps[i].pattrs = kcalloc(count, sizeof(struct powercap_attr),
>  					  GFP_KERNEL);
>  		if (!pcaps[i].pattrs)
>  			goto out_pcaps_pattrs;
>  
> -		pcaps[i].pg.attrs = kcalloc(j + 1, sizeof(struct attribute *),
> +		pcaps[i].pg.attrs = kcalloc(count + 1,
> +					    sizeof(struct attribute *),
>  					    GFP_KERNEL);
>  		if (!pcaps[i].pg.attrs) {
>  			kfree(pcaps[i].pattrs);
>  			goto out_pcaps_pattrs;
>  		}
>  
> -		j = 0;
>  		pcaps[i].pg.name = kasprintf(GFP_KERNEL, "%pOFn", node);
> -		if (has_min) {
> -			powercap_add_attr(min, "powercap-min",
> -					  &pcaps[i].pattrs[j]);
> -			pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr;
> -			j++;
> -		}
> -
> -		if (has_max) {
> -			powercap_add_attr(max, "powercap-max",
> -					  &pcaps[i].pattrs[j]);
> -			pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr;
> -			j++;
> -		}
> +		for (j = 0; j < ARRAY_SIZE(powercap_strs); j++) {
> +			if (of_property_read_u32(node, powercap_strs[j], &id))
> +				continue;
>  
> -		if (has_cur) {
> -			powercap_add_attr(cur, "powercap-current",
> +			powercap_add_attr(id, powercap_strs[j],
>  					  &pcaps[i].pattrs[j]);
> -			pcaps[i].pattrs[j].attr.attr.mode |= 0220;
> -			pcaps[i].pattrs[j].attr.store = powercap_store;
>  			pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr;
> -			j++;
>  		}
>  
>  		if (sysfs_create_group(powercap_kobj, &pcaps[i].pg)) {
> -- 
> 1.8.3.1

^ permalink raw reply

* Re: New IoT/M2M Communication Products with Cloud Service
From: Sales56 @ 2019-02-28  3:20 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <2019020028112000310095@xz.ls-tech.com>

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

Dear Manager,
 
Sorry to bother you.
 
Do you want to Monitor and Control your remote equipments via VPN, SMS and Cloud? 
Do you want to improve the Cellular, Serial, I/O, LoRaWAN connectivity in your solutions? 
We provide:
Industrial 4G LTE Router 
LoRaWAN Gateway 
Modbus-to-LoRa Converter 
Datalogger  
Remote I/O Controller
Reply me if you are interested in any related products above or just skip this E-mail.
Have a nice day!
☺☺

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

[-- Attachment #3: Photo --]
[-- Type: image/jpeg, Size: 63227 bytes --]

^ permalink raw reply

* [PATCH] powerpc: fix "sz" set but not used
From: Qian Cai @ 2019-02-28  2:35 UTC (permalink / raw)
  To: benh, paulus, mpe; +Cc: Qian Cai, linuxppc-dev, linux-kernel

arch/powerpc/mm/hugetlbpage-hash64.c: In function '__hash_page_huge':
arch/powerpc/mm/hugetlbpage-hash64.c:29:28: warning: variable 'sz' set
but not used [-Wunused-but-set-variable]

Signed-off-by: Qian Cai <cai@lca.pw>
---
 arch/powerpc/mm/hugetlbpage-hash64.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c
index 2e6a8f9345d3..f6b09edc5e6e 100644
--- a/arch/powerpc/mm/hugetlbpage-hash64.c
+++ b/arch/powerpc/mm/hugetlbpage-hash64.c
@@ -26,7 +26,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
 	real_pte_t rpte;
 	unsigned long vpn;
 	unsigned long old_pte, new_pte;
-	unsigned long rflags, pa, sz;
+	unsigned long rflags, pa;
 	long slot, offset;
 
 	BUG_ON(shift != mmu_psize_defs[mmu_psize].shift);
@@ -73,7 +73,6 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
 		offset = PTRS_PER_PMD;
 	rpte = __real_pte(__pte(old_pte), ptep, offset);
 
-	sz = ((1UL) << shift);
 	if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
 		/* No CPU has hugepages but lacks no execute, so we
 		 * don't need to worry about that case */
-- 
2.17.2 (Apple Git-113)


^ permalink raw reply related

* Re: [PATCH kernel] KVM: PPC: Allocate guest TCEs on demand too
From: David Gibson @ 2019-02-28  0:15 UTC (permalink / raw)
  To: Alexey Kardashevskiy; +Cc: linuxppc-dev, kvm-ppc
In-Reply-To: <20190227084235.22795-1-aik@ozlabs.ru>

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

On Wed, Feb 27, 2019 at 07:42:35PM +1100, Alexey Kardashevskiy wrote:
> We already allocate hardware TCE tables in multiple levels and skip
> intermediate levels when we can, now it is a turn of the KVM TCE tables.
> Thankfully these are allocated already in 2 levels.
> 
> This moves the table's last level allocation from the creating helper to
> kvmppc_tce_put() and kvm_spapr_tce_fault().
> 
> This adds kvmppc_rm_ioba_validate() to do an additional test if
> the consequent kvmppc_tce_put() needs a page which has not been allocated;
> if this is the case, we bail out to virtual mode handlers.
> 
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
> 
> For NVLink2 passthrough guests with 128TiB DMA windows (when we push GPU RAM
> above the PCI MMIO window in the guest) and very fragmented system RAM
> the difference is about 16GiB of RAM before and after this patch.
> 
> ---
>  arch/powerpc/kvm/book3s_64_vio.c    | 21 ++++------
>  arch/powerpc/kvm/book3s_64_vio_hv.c | 62 ++++++++++++++++++++++++++---
>  2 files changed, 64 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
> index f02b049..281b56b 100644
> --- a/arch/powerpc/kvm/book3s_64_vio.c
> +++ b/arch/powerpc/kvm/book3s_64_vio.c
> @@ -228,7 +228,8 @@ static void release_spapr_tce_table(struct rcu_head *head)
>  	unsigned long i, npages = kvmppc_tce_pages(stt->size);
>  
>  	for (i = 0; i < npages; i++)
> -		__free_page(stt->pages[i]);
> +		if (stt->pages[i])
> +			__free_page(stt->pages[i]);
>  
>  	kfree(stt);
>  }
> @@ -241,6 +242,12 @@ static vm_fault_t kvm_spapr_tce_fault(struct vm_fault *vmf)
>  	if (vmf->pgoff >= kvmppc_tce_pages(stt->size))
>  		return VM_FAULT_SIGBUS;
>  
> +	if (!stt->pages[vmf->pgoff]) {
> +		stt->pages[vmf->pgoff] = alloc_page(GFP_KERNEL | __GFP_ZERO);
> +		if (!stt->pages[vmf->pgoff])
> +			return VM_FAULT_OOM;
> +	}
> +
>  	page = stt->pages[vmf->pgoff];
>  	get_page(page);
>  	vmf->page = page;
> @@ -296,7 +303,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>  	struct kvmppc_spapr_tce_table *siter;
>  	unsigned long npages, size = args->size;
>  	int ret = -ENOMEM;
> -	int i;
>  
>  	if (!args->size || args->page_shift < 12 || args->page_shift > 34 ||
>  		(args->offset + args->size > (ULLONG_MAX >> args->page_shift)))
> @@ -320,12 +326,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>  	stt->kvm = kvm;
>  	INIT_LIST_HEAD_RCU(&stt->iommu_tables);
>  
> -	for (i = 0; i < npages; i++) {
> -		stt->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
> -		if (!stt->pages[i])
> -			goto fail;
> -	}
> -
>  	mutex_lock(&kvm->lock);
>  
>  	/* Check this LIOBN hasn't been previously allocated */
> @@ -352,11 +352,6 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>  	if (ret >= 0)
>  		return ret;
>  
> - fail:
> -	for (i = 0; i < npages; i++)
> -		if (stt->pages[i])
> -			__free_page(stt->pages[i]);
> -
>  	kfree(stt);
>   fail_acct:
>  	kvmppc_account_memlimit(kvmppc_stt_pages(npages), false);
> diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
> index 2206bc7..fbb920d 100644
> --- a/arch/powerpc/kvm/book3s_64_vio_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
> @@ -158,23 +158,69 @@ static u64 *kvmppc_page_address(struct page *page)
>  	return (u64 *) page_address(page);
>  }
>  
> +/*
> + * TCEs pages are allocated in kvmppc_tce_put() which won't be able to do so
> + * in real mode.
> + * Check if kvmppc_tce_put() can succeed in real mode, i.e. a TCEs page is
> + * allocated or not required (when clearing a tce entry).
> + */
> +static long kvmppc_rm_ioba_validate(struct kvmppc_spapr_tce_table *stt,
> +		unsigned long ioba, unsigned long npages, bool clearing)
> +{
> +	unsigned long i, sttpage, sttpages;
> +	unsigned long ret = kvmppc_ioba_validate(stt, ioba, npages);
> +
> +	if (ret)
> +		return ret;
> +	/*
> +	 * clearing==true says kvmppc_tce_put won't be allocating pages
> +	 * for empty tces.
> +	 */
> +	if (clearing)
> +		return H_SUCCESS;
> +
> +	sttpage = ((ioba >> stt->page_shift) - stt->offset) / TCES_PER_PAGE;
> +	sttpages = (npages + TCES_PER_PAGE - 1) / TCES_PER_PAGE;
> +	for (i = sttpage; i < sttpage + sttpages; ++i)
> +		if (!stt->pages[i])
> +			return H_TOO_HARD;
> +
> +	return H_SUCCESS;
> +}
> +
>  /*
>   * Handles TCE requests for emulated devices.
>   * Puts guest TCE values to the table and expects user space to convert them.
>   * Called in both real and virtual modes.
>   * Cannot fail so kvmppc_tce_validate must be called before it.
>   *
> - * WARNING: This will be called in real-mode on HV KVM and virtual
> - *          mode on PR KVM
> + * WARNING: This will be called in real-mode on HV HPT KVM and virtual
> + *          mode on PR KVM or HV radix KVM
>   */
>  void kvmppc_tce_put(struct kvmppc_spapr_tce_table *stt,
>  		unsigned long idx, unsigned long tce)
>  {
>  	struct page *page;
>  	u64 *tbl;
> +	unsigned long sttpage;
>  
>  	idx -= stt->offset;
> -	page = stt->pages[idx / TCES_PER_PAGE];
> +	sttpage = idx / TCES_PER_PAGE;
> +	page = stt->pages[sttpage];
> +
> +	if (!page) {
> +		/* We allow any TCE, not just with read|write permissions */
> +		if (!tce)
> +			return;
> +		/*
> +		 * We must not end up here in real mode,
> +		 * kvmppc_rm_ioba_validate() takes care of this.
> +		 */
> +		page = alloc_page(GFP_KERNEL | __GFP_ZERO);
> +		if (WARN_ON_ONCE(!page))
> +			return;
> +		stt->pages[sttpage] = page;
> +	}
>  	tbl = kvmppc_page_address(page);
>  
>  	tbl[idx % TCES_PER_PAGE] = tce;
> @@ -381,7 +427,7 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
>  	if (!stt)
>  		return H_TOO_HARD;
>  
> -	ret = kvmppc_ioba_validate(stt, ioba, 1);
> +	ret = kvmppc_rm_ioba_validate(stt, ioba, 1, tce == 0);
>  	if (ret != H_SUCCESS)
>  		return ret;
>  
> @@ -480,7 +526,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
>  	if (tce_list & (SZ_4K - 1))
>  		return H_PARAMETER;
>  
> -	ret = kvmppc_ioba_validate(stt, ioba, npages);
> +	ret = kvmppc_rm_ioba_validate(stt, ioba, npages, false);
>  	if (ret != H_SUCCESS)
>  		return ret;
>  
> @@ -583,7 +629,7 @@ long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu,
>  	if (!stt)
>  		return H_TOO_HARD;
>  
> -	ret = kvmppc_ioba_validate(stt, ioba, npages);
> +	ret = kvmppc_rm_ioba_validate(stt, ioba, npages, tce_value == 0);
>  	if (ret != H_SUCCESS)
>  		return ret;
>  
> @@ -635,6 +681,10 @@ long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
>  
>  	idx = (ioba >> stt->page_shift) - stt->offset;
>  	page = stt->pages[idx / TCES_PER_PAGE];
> +	if (!page) {
> +		vcpu->arch.regs.gpr[4] = 0;
> +		return H_SUCCESS;
> +	}
>  	tbl = (u64 *)page_address(page);
>  
>  	vcpu->arch.regs.gpr[4] = tbl[idx % TCES_PER_PAGE];

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v1 0/4] arm64: dts: NXP: add basic dts file for LX2160A SoC
From: Stephen Boyd @ 2019-02-28  0:01 UTC (permalink / raw)
  To: arnd@arndb.de, catalin.marinas@arm.com,
	devicetree@vger.kernel.org, gregkh@linuxfoundation.org,
	kstewart@linuxfoundation.org,
	linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org,
	linux-kernel-owner@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-pm@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	mark.rutland@arm.com, mturquette@baylibre.com, oss@buserror.net,
	rjw@rjwysocki.net, robh+dt@kernel.org, shawnguo@kernel.org,
	sudeep.holla@arm.com, viresh.kumar@lina ro.org,
	will.deacon@arm.com, yamada.masahiro@socionext.com, Leo Li,
	Vabhav Sharma
  Cc: ulf.hansson@linaro.org, linux@armlinux.org.uk, Vabhav Sharma,
	adrian.hunter@intel.com
In-Reply-To: <1551132245-6089-1-git-send-email-vabhav.sharma@nxp.com>

Quoting Vabhav Sharma (2019-02-26 02:10:46)
> These patches were reviewed and acked but dropped during merge window.
> Patchwork link was https://lore.kernel.org/patchwork/cover/1004155/
> 
> Changes for v1:
> - Updated lx2160a clockgen in alphabetical order
> 
> Vabhav Sharma (2):
>   dt-bindings: arm64: add compatible for LX2160A
>   soc/fsl/guts: Add definition for LX2160A
> 
> Yogesh Gaur (2):
>   clk: qoriq: increase array size of cmux_to_group
>   clk: qoriq: Add clockgen support for lx2160a

Who do you want to apply these patches?


^ permalink raw reply

* [PATCH] powerpc: fix "section_base" set but not used
From: Qian Cai @ 2019-02-27 22:11 UTC (permalink / raw)
  To: benh, paulus, mpe; +Cc: Qian Cai, linuxppc-dev, linux-kernel

arch/powerpc/mm/init_64.c: In function 'vmemmap_free':
arch/powerpc/mm/init_64.c:277:16: error: variable 'section_base' set but
not used [-Werror=unused-but-set-variable]

Signed-off-by: Qian Cai <cai@lca.pw>
---
 arch/powerpc/mm/init_64.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index a5091c034747..a4c155af1597 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -274,7 +274,6 @@ void __ref vmemmap_free(unsigned long start, unsigned long end,
 
 	for (; start < end; start += page_size) {
 		unsigned long nr_pages, addr;
-		struct page *section_base;
 		struct page *page;
 
 		/*
@@ -290,7 +289,6 @@ void __ref vmemmap_free(unsigned long start, unsigned long end,
 			continue;
 
 		page = pfn_to_page(addr >> PAGE_SHIFT);
-		section_base = pfn_to_page(vmemmap_section_start(start));
 		nr_pages = 1 << page_order;
 		base_pfn = PHYS_PFN(addr);
 
-- 
2.17.2 (Apple Git-113)


^ permalink raw reply related

* [PATCH v3 16/34] powerpc: mm: Add p?d_large() definitions
From: Steven Price @ 2019-02-27 17:05 UTC (permalink / raw)
  To: linux-mm
  Cc: Mark Rutland, Peter Zijlstra, Dave Hansen, Will Deacon,
	Paul Mackerras, H. Peter Anvin, Liang, Kan, x86, Steven Price,
	Ingo Molnar, Catalin Marinas, Arnd Bergmann, kvm-ppc,
	Jérôme Glisse, Borislav Petkov, Andy Lutomirski,
	Thomas Gleixner, linux-arm-kernel, Ard Biesheuvel, linux-kernel,
	James Morse, linuxppc-dev
In-Reply-To: <20190227170608.27963-1-steven.price@arm.com>

walk_page_range() is going to be allowed to walk page tables other than
those of user space. For this it needs to know when it has reached a
'leaf' entry in the page tables. This information is provided by the
p?d_large() functions/macros.

For powerpc pmd_large() was already implemented, so hoist it out of the
CONFIG_TRANSPARENT_HUGEPAGE condition and implement the other levels.

Also since we now have a pmd_large always implemented we can drop the
pmd_is_leaf() function.

For 32 bit simply implement stubs returning 0.

CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: Paul Mackerras <paulus@samba.org>
CC: Michael Ellerman <mpe@ellerman.id.au>
CC: linuxppc-dev@lists.ozlabs.org
CC: kvm-ppc@vger.kernel.org
Signed-off-by: Steven Price <steven.price@arm.com>
---
 arch/powerpc/include/asm/book3s/32/pgtable.h  |  1 +
 arch/powerpc/include/asm/book3s/64/pgtable.h  | 27 ++++++++++++-------
 arch/powerpc/include/asm/nohash/32/pgtable.h  |  1 +
 .../include/asm/nohash/64/pgtable-4k.h        |  1 +
 arch/powerpc/kvm/book3s_64_mmu_radix.c        | 12 +++------
 5 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 49d76adb9bc5..036052a792c8 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -202,6 +202,7 @@ extern unsigned long ioremap_bot;
 #define pmd_none(pmd)		(!pmd_val(pmd))
 #define	pmd_bad(pmd)		(pmd_val(pmd) & _PMD_BAD)
 #define	pmd_present(pmd)	(pmd_val(pmd) & _PMD_PRESENT_MASK)
+#define pmd_large(pmd)		(0)
 static inline void pmd_clear(pmd_t *pmdp)
 {
 	*pmdp = __pmd(0);
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index c9bfe526ca9d..1705b1a201bd 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -907,6 +907,11 @@ static inline int pud_present(pud_t pud)
 	return (pud_raw(pud) & cpu_to_be64(_PAGE_PRESENT));
 }
 
+static inline int pud_large(pud_t pud)
+{
+	return (pud_raw(pud) & cpu_to_be64(_PAGE_PTE));
+}
+
 extern struct page *pud_page(pud_t pud);
 extern struct page *pmd_page(pmd_t pmd);
 static inline pte_t pud_pte(pud_t pud)
@@ -954,6 +959,11 @@ static inline int pgd_present(pgd_t pgd)
 	return (pgd_raw(pgd) & cpu_to_be64(_PAGE_PRESENT));
 }
 
+static inline int pgd_large(pgd_t pgd)
+{
+	return (pgd_raw(pgd) & cpu_to_be64(_PAGE_PTE));
+}
+
 static inline pte_t pgd_pte(pgd_t pgd)
 {
 	return __pte_raw(pgd_raw(pgd));
@@ -1107,6 +1117,14 @@ static inline bool pmd_access_permitted(pmd_t pmd, bool write)
 	return pte_access_permitted(pmd_pte(pmd), write);
 }
 
+/*
+ * returns true for pmd migration entries, THP, devmap, hugetlb
+ */
+static inline int pmd_large(pmd_t pmd)
+{
+	return !!(pmd_raw(pmd) & cpu_to_be64(_PAGE_PTE));
+}
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 extern pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot);
 extern pmd_t mk_pmd(struct page *page, pgprot_t pgprot);
@@ -1133,15 +1151,6 @@ pmd_hugepage_update(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp,
 	return hash__pmd_hugepage_update(mm, addr, pmdp, clr, set);
 }
 
-/*
- * returns true for pmd migration entries, THP, devmap, hugetlb
- * But compile time dependent on THP config
- */
-static inline int pmd_large(pmd_t pmd)
-{
-	return !!(pmd_raw(pmd) & cpu_to_be64(_PAGE_PTE));
-}
-
 static inline pmd_t pmd_mknotpresent(pmd_t pmd)
 {
 	return __pmd(pmd_val(pmd) & ~_PAGE_PRESENT);
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index bed433358260..ebd55449914b 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -190,6 +190,7 @@ static inline pte_t pte_mkexec(pte_t pte)
 #define pmd_none(pmd)		(!pmd_val(pmd))
 #define	pmd_bad(pmd)		(pmd_val(pmd) & _PMD_BAD)
 #define	pmd_present(pmd)	(pmd_val(pmd) & _PMD_PRESENT_MASK)
+#define pmd_large(pmd)		(0)
 static inline void pmd_clear(pmd_t *pmdp)
 {
 	*pmdp = __pmd(0);
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable-4k.h b/arch/powerpc/include/asm/nohash/64/pgtable-4k.h
index c40ec32b8194..9e6fa5646c9f 100644
--- a/arch/powerpc/include/asm/nohash/64/pgtable-4k.h
+++ b/arch/powerpc/include/asm/nohash/64/pgtable-4k.h
@@ -56,6 +56,7 @@
 #define pgd_none(pgd)		(!pgd_val(pgd))
 #define pgd_bad(pgd)		(pgd_val(pgd) == 0)
 #define pgd_present(pgd)	(pgd_val(pgd) != 0)
+#define pgd_large(pgd)		(0)
 #define pgd_page_vaddr(pgd)	(pgd_val(pgd) & ~PGD_MASKED_BITS)
 
 #ifndef __ASSEMBLY__
diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c
index 1b821c6efdef..040db20ac2ab 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_radix.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c
@@ -363,12 +363,6 @@ static void kvmppc_pte_free(pte_t *ptep)
 	kmem_cache_free(kvm_pte_cache, ptep);
 }
 
-/* Like pmd_huge() and pmd_large(), but works regardless of config options */
-static inline int pmd_is_leaf(pmd_t pmd)
-{
-	return !!(pmd_val(pmd) & _PAGE_PTE);
-}
-
 static pmd_t *kvmppc_pmd_alloc(void)
 {
 	return kmem_cache_alloc(kvm_pmd_cache, GFP_KERNEL);
@@ -455,7 +449,7 @@ static void kvmppc_unmap_free_pmd(struct kvm *kvm, pmd_t *pmd, bool full,
 	for (im = 0; im < PTRS_PER_PMD; ++im, ++p) {
 		if (!pmd_present(*p))
 			continue;
-		if (pmd_is_leaf(*p)) {
+		if (pmd_large(*p)) {
 			if (full) {
 				pmd_clear(p);
 			} else {
@@ -588,7 +582,7 @@ int kvmppc_create_pte(struct kvm *kvm, pgd_t *pgtable, pte_t pte,
 	else if (level <= 1)
 		new_pmd = kvmppc_pmd_alloc();
 
-	if (level == 0 && !(pmd && pmd_present(*pmd) && !pmd_is_leaf(*pmd)))
+	if (level == 0 && !(pmd && pmd_present(*pmd) && !pmd_large(*pmd)))
 		new_ptep = kvmppc_pte_alloc();
 
 	/* Check if we might have been invalidated; let the guest retry if so */
@@ -657,7 +651,7 @@ int kvmppc_create_pte(struct kvm *kvm, pgd_t *pgtable, pte_t pte,
 		new_pmd = NULL;
 	}
 	pmd = pmd_offset(pud, gpa);
-	if (pmd_is_leaf(*pmd)) {
+	if (pmd_large(*pmd)) {
 		unsigned long lgpa = gpa & PMD_MASK;
 
 		/* Check if we raced and someone else has set the same thing */
-- 
2.20.1


^ permalink raw reply related

* Re: [RESEND PATCH 0/7] Add FOLL_LONGTERM to GUP fast and use it
From: Ira Weiny @ 2019-02-27 19:14 UTC (permalink / raw)
  To: John Hubbard, Andrew Morton, Michal Hocko, Kirill A. Shutemov,
	Peter Zijlstra, Jason Gunthorpe, Benjamin Herrenschmidt,
	Paul Mackerras, David S. Miller, Martin Schwidefsky,
	Heiko Carstens, Rich Felker, Yoshinori Sato, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, Ralf Baechle, Paul Burton,
	James Hogan
  Cc: linux-fbdev, kvm, linux-sh, linux-fpga, dri-devel, linux-mips,
	linux-mm, sparclinux, devel, linux-s390, rds-devel, linux-scsi,
	linux-rdma, xen-devel, devel, linux-media, kvm-ppc, ceph-devel,
	virtualization, netdev, linux-kernel, linuxppc-dev
In-Reply-To: <20190220053040.10831-1-ira.weiny@intel.com>

On Tue, Feb 19, 2019 at 09:30:33PM -0800, 'Ira Weiny' wrote:
> From: Ira Weiny <ira.weiny@intel.com>
> 
> Resending these as I had only 1 minor comment which I believe we have covered
> in this series.  I was anticipating these going through the mm tree as they
> depend on a cleanup patch there and the IB changes are very minor.  But they
> could just as well go through the IB tree.
> 
> NOTE: This series depends on my clean up patch to remove the write parameter
> from gup_fast_permitted()[1]
> 
> HFI1, qib, and mthca, use get_user_pages_fast() due to it performance
> advantages.  These pages can be held for a significant time.  But
> get_user_pages_fast() does not protect against mapping of FS DAX pages.
> 
> Introduce FOLL_LONGTERM and use this flag in get_user_pages_fast() which
> retains the performance while also adding the FS DAX checks.  XDP has also
> shown interest in using this functionality.[2]
> 
> In addition we change get_user_pages() to use the new FOLL_LONGTERM flag and
> remove the specialized get_user_pages_longterm call.
> 
> [1] https://lkml.org/lkml/2019/2/11/237
> [2] https://lkml.org/lkml/2019/2/11/1789

Is there anything I need to do on this series or does anyone have any
objections to it going into 5.1?  And if so who's tree is it going to go
through?

Thanks,
Ira

> 
> Ira Weiny (7):
>   mm/gup: Replace get_user_pages_longterm() with FOLL_LONGTERM
>   mm/gup: Change write parameter to flags in fast walk
>   mm/gup: Change GUP fast to use flags rather than a write 'bool'
>   mm/gup: Add FOLL_LONGTERM capability to GUP fast
>   IB/hfi1: Use the new FOLL_LONGTERM flag to get_user_pages_fast()
>   IB/qib: Use the new FOLL_LONGTERM flag to get_user_pages_fast()
>   IB/mthca: Use the new FOLL_LONGTERM flag to get_user_pages_fast()
> 
>  arch/mips/mm/gup.c                          |  11 +-
>  arch/powerpc/kvm/book3s_64_mmu_hv.c         |   4 +-
>  arch/powerpc/kvm/e500_mmu.c                 |   2 +-
>  arch/powerpc/mm/mmu_context_iommu.c         |   4 +-
>  arch/s390/kvm/interrupt.c                   |   2 +-
>  arch/s390/mm/gup.c                          |  12 +-
>  arch/sh/mm/gup.c                            |  11 +-
>  arch/sparc/mm/gup.c                         |   9 +-
>  arch/x86/kvm/paging_tmpl.h                  |   2 +-
>  arch/x86/kvm/svm.c                          |   2 +-
>  drivers/fpga/dfl-afu-dma-region.c           |   2 +-
>  drivers/gpu/drm/via/via_dmablit.c           |   3 +-
>  drivers/infiniband/core/umem.c              |   5 +-
>  drivers/infiniband/hw/hfi1/user_pages.c     |   5 +-
>  drivers/infiniband/hw/mthca/mthca_memfree.c |   3 +-
>  drivers/infiniband/hw/qib/qib_user_pages.c  |   8 +-
>  drivers/infiniband/hw/qib/qib_user_sdma.c   |   2 +-
>  drivers/infiniband/hw/usnic/usnic_uiom.c    |   9 +-
>  drivers/media/v4l2-core/videobuf-dma-sg.c   |   6 +-
>  drivers/misc/genwqe/card_utils.c            |   2 +-
>  drivers/misc/vmw_vmci/vmci_host.c           |   2 +-
>  drivers/misc/vmw_vmci/vmci_queue_pair.c     |   6 +-
>  drivers/platform/goldfish/goldfish_pipe.c   |   3 +-
>  drivers/rapidio/devices/rio_mport_cdev.c    |   4 +-
>  drivers/sbus/char/oradax.c                  |   2 +-
>  drivers/scsi/st.c                           |   3 +-
>  drivers/staging/gasket/gasket_page_table.c  |   4 +-
>  drivers/tee/tee_shm.c                       |   2 +-
>  drivers/vfio/vfio_iommu_spapr_tce.c         |   3 +-
>  drivers/vfio/vfio_iommu_type1.c             |   3 +-
>  drivers/vhost/vhost.c                       |   2 +-
>  drivers/video/fbdev/pvr2fb.c                |   2 +-
>  drivers/virt/fsl_hypervisor.c               |   2 +-
>  drivers/xen/gntdev.c                        |   2 +-
>  fs/orangefs/orangefs-bufmap.c               |   2 +-
>  include/linux/mm.h                          |  17 +-
>  kernel/futex.c                              |   2 +-
>  lib/iov_iter.c                              |   7 +-
>  mm/gup.c                                    | 220 ++++++++++++--------
>  mm/gup_benchmark.c                          |   5 +-
>  mm/util.c                                   |   8 +-
>  net/ceph/pagevec.c                          |   2 +-
>  net/rds/info.c                              |   2 +-
>  net/rds/rdma.c                              |   3 +-
>  44 files changed, 232 insertions(+), 180 deletions(-)
> 
> -- 
> 2.20.1
> 

^ permalink raw reply

* Re: [PATCH 1/5] ocxl: Rename struct link to ocxl_link
From: Greg Kurz @ 2019-02-27 13:53 UTC (permalink / raw)
  To: Alastair D'Silva
  Cc: Arnd Bergmann, Greg Kroah-Hartman, linux-kernel, Andrew Donnellan,
	alastair, Frederic Barrat, linuxppc-dev
In-Reply-To: <20190227045741.21412-2-alastair@au1.ibm.com>

On Wed, 27 Feb 2019 15:57:37 +1100
"Alastair D'Silva" <alastair@au1.ibm.com> wrote:

> From: Alastair D'Silva <alastair@d-silva.org>
> 
> The term 'link' is ambiguous (especially when the struct is used for a
> list), so rename it for clarity.
> 
> Signed-off-by: Alastair D'Silva <alastair@d-silva.org>
> Reviewed-by: Greg Kurz <groug@kaod.org>
> ---
>  drivers/misc/ocxl/file.c |  2 +-
>  drivers/misc/ocxl/link.c | 36 ++++++++++++++++++------------------
>  2 files changed, 19 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c
> index e6a607488f8a..16eb8a60d5c7 100644
> --- a/drivers/misc/ocxl/file.c
> +++ b/drivers/misc/ocxl/file.c
> @@ -152,7 +152,7 @@ static long afu_ioctl_enable_p9_wait(struct ocxl_context *ctx,
>  
>  		if (status == ATTACHED) {
>  			int rc;
> -			struct link *link = ctx->afu->fn->link;
> +			void *link = ctx->afu->fn->link;
> 

Thinking about that again, the link variable only has one user. Irrespectively
of the discussion on adding a struct ocxl_link forward declaration in the
private header and changing the API, link isn't needed in the first place...
 
>  			rc = ocxl_link_update_pe(link, ctx->pasid, ctx->tidr);

... and we could just do:

			rc = ocxl_link_update_pe(ctx->afu->fn->link, ctx->pasid,
						 ctx->tidr);

I guess it is acceptable to do this change "while here" since the patch is
about dropping the ambiguous 'link' term.

>  			if (rc)
> diff --git a/drivers/misc/ocxl/link.c b/drivers/misc/ocxl/link.c
> index d50b861d7e57..8d2690a1a9de 100644
> --- a/drivers/misc/ocxl/link.c
> +++ b/drivers/misc/ocxl/link.c
> @@ -76,7 +76,7 @@ struct spa {
>   * limited number of opencapi slots on a system and lookup is only
>   * done when the device is probed
>   */
> -struct link {
> +struct ocxl_link {
>  	struct list_head list;
>  	struct kref ref;
>  	int domain;
> @@ -179,7 +179,7 @@ static void xsl_fault_handler_bh(struct work_struct *fault_work)
>  
>  static irqreturn_t xsl_fault_handler(int irq, void *data)
>  {
> -	struct link *link = (struct link *) data;
> +	struct ocxl_link *link = (struct ocxl_link *) data;
>  	struct spa *spa = link->spa;
>  	u64 dsisr, dar, pe_handle;
>  	struct pe_data *pe_data;
> @@ -256,7 +256,7 @@ static int map_irq_registers(struct pci_dev *dev, struct spa *spa)
>  				&spa->reg_tfc, &spa->reg_pe_handle);
>  }
>  
> -static int setup_xsl_irq(struct pci_dev *dev, struct link *link)
> +static int setup_xsl_irq(struct pci_dev *dev, struct ocxl_link *link)
>  {
>  	struct spa *spa = link->spa;
>  	int rc;
> @@ -311,7 +311,7 @@ static int setup_xsl_irq(struct pci_dev *dev, struct link *link)
>  	return rc;
>  }
>  
> -static void release_xsl_irq(struct link *link)
> +static void release_xsl_irq(struct ocxl_link *link)
>  {
>  	struct spa *spa = link->spa;
>  
> @@ -323,7 +323,7 @@ static void release_xsl_irq(struct link *link)
>  	unmap_irq_registers(spa);
>  }
>  
> -static int alloc_spa(struct pci_dev *dev, struct link *link)
> +static int alloc_spa(struct pci_dev *dev, struct ocxl_link *link)
>  {
>  	struct spa *spa;
>  
> @@ -350,7 +350,7 @@ static int alloc_spa(struct pci_dev *dev, struct link *link)
>  	return 0;
>  }
>  
> -static void free_spa(struct link *link)
> +static void free_spa(struct ocxl_link *link)
>  {
>  	struct spa *spa = link->spa;
>  
> @@ -364,12 +364,12 @@ static void free_spa(struct link *link)
>  	}
>  }
>  
> -static int alloc_link(struct pci_dev *dev, int PE_mask, struct link **out_link)
> +static int alloc_link(struct pci_dev *dev, int PE_mask, struct ocxl_link **out_link)
>  {
> -	struct link *link;
> +	struct ocxl_link *link;
>  	int rc;
>  
> -	link = kzalloc(sizeof(struct link), GFP_KERNEL);
> +	link = kzalloc(sizeof(struct ocxl_link), GFP_KERNEL);
>  	if (!link)
>  		return -ENOMEM;
>  
> @@ -405,7 +405,7 @@ static int alloc_link(struct pci_dev *dev, int PE_mask, struct link **out_link)
>  	return rc;
>  }
>  
> -static void free_link(struct link *link)
> +static void free_link(struct ocxl_link *link)
>  {
>  	release_xsl_irq(link);
>  	free_spa(link);
> @@ -415,7 +415,7 @@ static void free_link(struct link *link)
>  int ocxl_link_setup(struct pci_dev *dev, int PE_mask, void **link_handle)
>  {
>  	int rc = 0;
> -	struct link *link;
> +	struct ocxl_link *link;
>  
>  	mutex_lock(&links_list_lock);
>  	list_for_each_entry(link, &links_list, list) {
> @@ -442,7 +442,7 @@ EXPORT_SYMBOL_GPL(ocxl_link_setup);
>  
>  static void release_xsl(struct kref *ref)
>  {
> -	struct link *link = container_of(ref, struct link, ref);
> +	struct ocxl_link *link = container_of(ref, struct ocxl_link, ref);
>  
>  	list_del(&link->list);
>  	/* call platform code before releasing data */
> @@ -452,7 +452,7 @@ static void release_xsl(struct kref *ref)
>  
>  void ocxl_link_release(struct pci_dev *dev, void *link_handle)
>  {
> -	struct link *link = (struct link *) link_handle;
> +	struct ocxl_link *link = (struct ocxl_link *) link_handle;
>  
>  	mutex_lock(&links_list_lock);
>  	kref_put(&link->ref, release_xsl);
> @@ -488,7 +488,7 @@ int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr,
>  		void (*xsl_err_cb)(void *data, u64 addr, u64 dsisr),
>  		void *xsl_err_data)
>  {
> -	struct link *link = (struct link *) link_handle;
> +	struct ocxl_link *link = (struct ocxl_link *) link_handle;
>  	struct spa *spa = link->spa;
>  	struct ocxl_process_element *pe;
>  	int pe_handle, rc = 0;
> @@ -558,7 +558,7 @@ EXPORT_SYMBOL_GPL(ocxl_link_add_pe);
>  
>  int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid)
>  {
> -	struct link *link = (struct link *) link_handle;
> +	struct ocxl_link *link = (struct ocxl_link *) link_handle;
>  	struct spa *spa = link->spa;
>  	struct ocxl_process_element *pe;
>  	int pe_handle, rc;
> @@ -594,7 +594,7 @@ int ocxl_link_update_pe(void *link_handle, int pasid, __u16 tid)
>  
>  int ocxl_link_remove_pe(void *link_handle, int pasid)
>  {
> -	struct link *link = (struct link *) link_handle;
> +	struct ocxl_link *link = (struct ocxl_link *) link_handle;
>  	struct spa *spa = link->spa;
>  	struct ocxl_process_element *pe;
>  	struct pe_data *pe_data;
> @@ -666,7 +666,7 @@ EXPORT_SYMBOL_GPL(ocxl_link_remove_pe);
>  
>  int ocxl_link_irq_alloc(void *link_handle, int *hw_irq, u64 *trigger_addr)
>  {
> -	struct link *link = (struct link *) link_handle;
> +	struct ocxl_link *link = (struct ocxl_link *) link_handle;
>  	int rc, irq;
>  	u64 addr;
>  
> @@ -687,7 +687,7 @@ EXPORT_SYMBOL_GPL(ocxl_link_irq_alloc);
>  
>  void ocxl_link_free_irq(void *link_handle, int hw_irq)
>  {
> -	struct link *link = (struct link *) link_handle;
> +	struct ocxl_link *link = (struct ocxl_link *) link_handle;
>  
>  	pnv_ocxl_free_xive_irq(hw_irq);
>  	atomic_inc(&link->irq_available);


^ permalink raw reply

* Re: [RFC PATCH v2 09/14] watchdog/hardlockup: Make arch_touch_nmi_watchdog() to hpet-based implementation
From: Paul E. McKenney @ 2019-02-27 16:17 UTC (permalink / raw)
  To: Ricardo Neri
  Cc: Rafael J. Wysocki, Peter Zijlstra, Alexei Starovoitov,
	Kai-Heng Feng, Paul Mackerras, H. Peter Anvin, sparclinux,
	Ingo Molnar, Christoffer Dall, Davidlohr Bueso, Ashok Raj, x86,
	David Rientjes, Andi Kleen, Waiman Long, Borislav Petkov,
	Don Zickus, Ravi V. Shankar, Konrad Rzeszutek Wilk, Marc Zyngier,
	Frederic Weisbecker, Nicholas Piggin, Ricardo Neri,
	Byungchul Park, Mathieu Desnoyers, Josh Poimboeuf,
	Thomas Gleixner, Tony Luck, Babu Moger, Randy Dunlap,
	linux-kernel, Luis R. Rodriguez, Masami Hiramatsu,
	Philippe Ombredanne, Colin Ian King, Andrew Morton, linuxppc-dev,
	David S. Miller
In-Reply-To: <1551283518-18922-10-git-send-email-ricardo.neri-calderon@linux.intel.com>

On Wed, Feb 27, 2019 at 08:05:13AM -0800, Ricardo Neri wrote:
> CPU architectures that have an NMI watchdog use arch_touch_nmi_watchdog()
> to briefly ignore the hardlockup detector. If the architecture does not
> have an NMI watchdog, one can be constructed using a source of non-
> maskable interrupts. In this case, arch_touch_nmi_watchdog() is common
> to any underlying hardware resource used to drive the detector and needs
> to be available to other kernel subsystems if hardware different from perf
> drives the detector.
> 
> There exists perf-based and HPET-based implementations. Make it available
> to the latter.
> 
> For clarity, wrap this function in a separate preprocessor conditional
> from functions which are truly specific to the perf-based implementation.
> 
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: Ashok Raj <ashok.raj@intel.com>
> Cc: Andi Kleen <andi.kleen@intel.com>
> Cc: Tony Luck <tony.luck@intel.com>
> Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
> Cc: Don Zickus <dzickus@redhat.com>
> Cc: Nicholas Piggin <npiggin@gmail.com>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Frederic Weisbecker <frederic@kernel.org>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: Babu Moger <babu.moger@oracle.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> Cc: Masami Hiramatsu <mhiramat@kernel.org>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Philippe Ombredanne <pombredanne@nexb.com>
> Cc: Colin Ian King <colin.king@canonical.com>
> Cc: Byungchul Park <byungchul.park@lge.com>
> Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
> Cc: "Luis R. Rodriguez" <mcgrof@kernel.org>
> Cc: Waiman Long <longman@redhat.com>
> Cc: Josh Poimboeuf <jpoimboe@redhat.com>
> Cc: Randy Dunlap <rdunlap@infradead.org>
> Cc: Davidlohr Bueso <dave@stgolabs.net>
> Cc: Christoffer Dall <cdall@linaro.org>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Kai-Heng Feng <kai.heng.feng@canonical.com>
> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> Cc: David Rientjes <rientjes@google.com>
> Cc: "Ravi V. Shankar" <ravi.v.shankar@intel.com>
> Cc: x86@kernel.org
> Cc: sparclinux@vger.kernel.org
> Cc: linuxppc-dev@lists.ozlabs.org
> Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
> ---
>  include/linux/nmi.h | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/nmi.h b/include/linux/nmi.h
> index 5a8b19749769..bf5ebcfdd590 100644
> --- a/include/linux/nmi.h
> +++ b/include/linux/nmi.h
> @@ -94,8 +94,16 @@ static inline void hardlockup_detector_disable(void) {}
>  # define NMI_WATCHDOG_SYSCTL_PERM	0444
>  #endif
> 
> -#if defined(CONFIG_HARDLOCKUP_DETECTOR_PERF)
> +#if defined(CONFIG_HARDLOCKUP_DETECTOR_PERF) || \
> +    defined(CONFIG_X86_HARDLOCKUP_DETECTOR_HPET)

Why not instead make CONFIG_X86_HARDLOCKUP_DETECTOR_HPET select
CONFIG_HARDLOCKUP_DETECTOR_PERF?  Keep the arch-specific details
in the arch-specific files and all that.

							Thanx, Paul

>  extern void arch_touch_nmi_watchdog(void);
> +#else
> +# if !defined(CONFIG_HAVE_NMI_WATCHDOG)
> +static inline void arch_touch_nmi_watchdog(void) {}
> +# endif
> +#endif
> +
> +#if defined(CONFIG_HARDLOCKUP_DETECTOR_PERF)
>  extern void hardlockup_detector_perf_stop(void);
>  extern void hardlockup_detector_perf_restart(void);
>  extern void hardlockup_detector_perf_disable(void);
> -- 
> 2.17.1
> 


^ permalink raw reply

* [RFC PATCH v2 10/14] kernel/watchdog: Add a function to obtain the watchdog_allowed_mask
From: Ricardo Neri @ 2019-02-27 16:05 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, Borislav Petkov
  Cc: Rafael J. Wysocki, Peter Zijlstra, Alexei Starovoitov,
	Kai-Heng Feng, Paul Mackerras, H. Peter Anvin, sparclinux,
	Christoffer Dall, Davidlohr Bueso, Ashok Raj, x86, David Rientjes,
	Andi Kleen, Waiman Long, Paul E. McKenney, Don Zickus,
	Ravi V. Shankar, Konrad Rzeszutek Wilk, Marc Zyngier,
	Ricardo Neri, Frederic Weisbecker, Nicholas Piggin, Ricardo Neri,
	Byungchul Park, Mathieu Desnoyers, Josh Poimboeuf, Tony Luck,
	Babu Moger, Randy Dunlap, linux-kernel, Luis R. Rodriguez,
	Masami Hiramatsu, Philippe Ombredanne, Colin Ian King,
	Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <1551283518-18922-1-git-send-email-ricardo.neri-calderon@linux.intel.com>

Implementations of NMI watchdogs that use a single piece of hardware to
monitor all the CPUs in the system (as opposed to per-CPU implementations
such as perf) need to know which CPUs the watchdog is allowed to monitor.
In this manner, non-maskable interrupts are directed only to the monitored
CPUs.

Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Andi Kleen <andi.kleen@intel.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Babu Moger <babu.moger@oracle.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Philippe Ombredanne <pombredanne@nexb.com>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Byungchul Park <byungchul.park@lge.com>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: "Luis R. Rodriguez" <mcgrof@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Christoffer Dall <cdall@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Kai-Heng Feng <kai.heng.feng@canonical.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: David Rientjes <rientjes@google.com>
Cc: "Ravi V. Shankar" <ravi.v.shankar@intel.com>
Cc: x86@kernel.org
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: sparclinux@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
---
 include/linux/nmi.h | 1 +
 kernel/watchdog.c   | 7 ++++++-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/include/linux/nmi.h b/include/linux/nmi.h
index bf5ebcfdd590..b563fb6ef21d 100644
--- a/include/linux/nmi.h
+++ b/include/linux/nmi.h
@@ -83,6 +83,7 @@ static inline void reset_hung_task_detector(void) { }
 
 #if defined(CONFIG_HARDLOCKUP_DETECTOR)
 extern void hardlockup_detector_disable(void);
+extern struct cpumask *watchdog_get_allowed_cpumask(void);
 extern unsigned int hardlockup_panic;
 #else
 static inline void hardlockup_detector_disable(void) {}
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 8fbfda94a67b..367aa81294ef 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -44,7 +44,7 @@ int __read_mostly soft_watchdog_user_enabled = 1;
 int __read_mostly watchdog_thresh = 10;
 int __read_mostly nmi_watchdog_available;
 
-struct cpumask watchdog_allowed_mask __read_mostly;
+static struct cpumask watchdog_allowed_mask __read_mostly;
 
 struct cpumask watchdog_cpumask __read_mostly;
 unsigned long *watchdog_cpumask_bits = cpumask_bits(&watchdog_cpumask);
@@ -92,6 +92,11 @@ static int __init hardlockup_all_cpu_backtrace_setup(char *str)
 }
 __setup("hardlockup_all_cpu_backtrace=", hardlockup_all_cpu_backtrace_setup);
 # endif /* CONFIG_SMP */
+
+struct cpumask *watchdog_get_allowed_cpumask(void)
+{
+	return &watchdog_allowed_mask;
+}
 #endif /* CONFIG_HARDLOCKUP_DETECTOR */
 
 /*
-- 
2.17.1


^ permalink raw reply related

* [RFC PATCH v2 09/14] watchdog/hardlockup: Make arch_touch_nmi_watchdog() to hpet-based implementation
From: Ricardo Neri @ 2019-02-27 16:05 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, Borislav Petkov
  Cc: Rafael J. Wysocki, Peter Zijlstra, Alexei Starovoitov,
	Kai-Heng Feng, Paul Mackerras, H. Peter Anvin, sparclinux,
	Christoffer Dall, Davidlohr Bueso, Ashok Raj, x86, David Rientjes,
	Andi Kleen, Waiman Long, Paul E. McKenney, Don Zickus,
	Ravi V. Shankar, Konrad Rzeszutek Wilk, Marc Zyngier,
	Ricardo Neri, Frederic Weisbecker, Nicholas Piggin, Ricardo Neri,
	Byungchul Park, Mathieu Desnoyers, Josh Poimboeuf, Tony Luck,
	Babu Moger, Randy Dunlap, linux-kernel, Luis R. Rodriguez,
	Masami Hiramatsu, Philippe Ombredanne, Colin Ian King,
	Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <1551283518-18922-1-git-send-email-ricardo.neri-calderon@linux.intel.com>

CPU architectures that have an NMI watchdog use arch_touch_nmi_watchdog()
to briefly ignore the hardlockup detector. If the architecture does not
have an NMI watchdog, one can be constructed using a source of non-
maskable interrupts. In this case, arch_touch_nmi_watchdog() is common
to any underlying hardware resource used to drive the detector and needs
to be available to other kernel subsystems if hardware different from perf
drives the detector.

There exists perf-based and HPET-based implementations. Make it available
to the latter.

For clarity, wrap this function in a separate preprocessor conditional
from functions which are truly specific to the perf-based implementation.

Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Andi Kleen <andi.kleen@intel.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Babu Moger <babu.moger@oracle.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Philippe Ombredanne <pombredanne@nexb.com>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: Byungchul Park <byungchul.park@lge.com>
Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
Cc: "Luis R. Rodriguez" <mcgrof@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Christoffer Dall <cdall@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Kai-Heng Feng <kai.heng.feng@canonical.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: David Rientjes <rientjes@google.com>
Cc: "Ravi V. Shankar" <ravi.v.shankar@intel.com>
Cc: x86@kernel.org
Cc: sparclinux@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
---
 include/linux/nmi.h | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/include/linux/nmi.h b/include/linux/nmi.h
index 5a8b19749769..bf5ebcfdd590 100644
--- a/include/linux/nmi.h
+++ b/include/linux/nmi.h
@@ -94,8 +94,16 @@ static inline void hardlockup_detector_disable(void) {}
 # define NMI_WATCHDOG_SYSCTL_PERM	0444
 #endif
 
-#if defined(CONFIG_HARDLOCKUP_DETECTOR_PERF)
+#if defined(CONFIG_HARDLOCKUP_DETECTOR_PERF) || \
+    defined(CONFIG_X86_HARDLOCKUP_DETECTOR_HPET)
 extern void arch_touch_nmi_watchdog(void);
+#else
+# if !defined(CONFIG_HAVE_NMI_WATCHDOG)
+static inline void arch_touch_nmi_watchdog(void) {}
+# endif
+#endif
+
+#if defined(CONFIG_HARDLOCKUP_DETECTOR_PERF)
 extern void hardlockup_detector_perf_stop(void);
 extern void hardlockup_detector_perf_restart(void);
 extern void hardlockup_detector_perf_disable(void);
-- 
2.17.1


^ permalink raw reply related

* [RFC PATCH v2 07/14] watchdog/hardlockup: Define a generic function to detect hardlockups
From: Ricardo Neri @ 2019-02-27 16:05 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, Borislav Petkov
  Cc: Peter Zijlstra, Ricardo Neri, Paul Mackerras, H. Peter Anvin,
	sparclinux, Ashok Raj, x86, Andi Kleen, Don Zickus,
	Ravi V. Shankar, Ricardo Neri, Frederic Weisbecker,
	Nicholas Piggin, Mathieu Desnoyers, Tony Luck, Babu Moger,
	linux-kernel, Luis R. Rodriguez, Masami Hiramatsu,
	Philippe Ombredanne, Colin Ian King, Andrew Morton, linuxppc-dev,
	David S. Miller
In-Reply-To: <1551283518-18922-1-git-send-email-ricardo.neri-calderon@linux.intel.com>

The procedure to detect hardlockups is independent of the underlying
mechanism that generated the non-maskable interrupt used to drive the
detector. Thus, it can be put in a separate, generic function. In this
manner, it can be invoked by various implementations of the NMI watchdog.

For this purpose, move the bulk of watchdog_overflow_callback() to the
new function inspect_for_hardlockups(). This function can then be called
from the applicable NMI handlers.

Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Andi Kleen <andi.kleen@intel.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Babu Moger <babu.moger@oracle.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Philippe Ombredanne <pombredanne@nexb.com>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: "Luis R. Rodriguez" <mcgrof@kernel.org>
Cc: "Ravi V. Shankar" <ravi.v.shankar@intel.com>
Cc: x86@kernel.org
Cc: sparclinux@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
---
 include/linux/nmi.h   |  1 +
 kernel/watchdog_hld.c | 18 +++++++++++-------
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/include/linux/nmi.h b/include/linux/nmi.h
index 9003e29cde46..5a8b19749769 100644
--- a/include/linux/nmi.h
+++ b/include/linux/nmi.h
@@ -212,6 +212,7 @@ extern int proc_watchdog_thresh(struct ctl_table *, int ,
 				void __user *, size_t *, loff_t *);
 extern int proc_watchdog_cpumask(struct ctl_table *, int,
 				 void __user *, size_t *, loff_t *);
+void inspect_for_hardlockups(struct pt_regs *regs);
 
 #ifdef CONFIG_HAVE_ACPI_APEI_NMI
 #include <asm/nmi.h>
diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c
index 71381168dede..9724cd57307b 100644
--- a/kernel/watchdog_hld.c
+++ b/kernel/watchdog_hld.c
@@ -106,14 +106,8 @@ static struct perf_event_attr wd_hw_attr = {
 	.disabled	= 1,
 };
 
-/* Callback function for perf event subsystem */
-static void watchdog_overflow_callback(struct perf_event *event,
-				       struct perf_sample_data *data,
-				       struct pt_regs *regs)
+void inspect_for_hardlockups(struct pt_regs *regs)
 {
-	/* Ensure the watchdog never gets throttled */
-	event->hw.interrupts = 0;
-
 	if (__this_cpu_read(watchdog_nmi_touch) == true) {
 		__this_cpu_write(watchdog_nmi_touch, false);
 		return;
@@ -162,6 +156,16 @@ static void watchdog_overflow_callback(struct perf_event *event,
 	return;
 }
 
+/* Callback function for perf event subsystem */
+static void watchdog_overflow_callback(struct perf_event *event,
+				       struct perf_sample_data *data,
+				       struct pt_regs *regs)
+{
+	/* Ensure the watchdog never gets throttled */
+	event->hw.interrupts = 0;
+	inspect_for_hardlockups(regs);
+}
+
 static int hardlockup_detector_event_create(void)
 {
 	unsigned int cpu = smp_processor_id();
-- 
2.17.1


^ permalink raw reply related

* [RFC PATCH v2 08/14] watchdog/hardlockup: Decouple the hardlockup detector from perf
From: Ricardo Neri @ 2019-02-27 16:05 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, Borislav Petkov
  Cc: Peter Zijlstra, Ricardo Neri, Paul Mackerras, H. Peter Anvin,
	sparclinux, Ashok Raj, x86, Andi Kleen, Don Zickus,
	Ravi V. Shankar, Ricardo Neri, Frederic Weisbecker,
	Nicholas Piggin, Mathieu Desnoyers, Tony Luck, Babu Moger,
	linux-kernel, Luis R. Rodriguez, Masami Hiramatsu,
	Philippe Ombredanne, Colin Ian King, Andrew Morton, linuxppc-dev,
	David S. Miller
In-Reply-To: <1551283518-18922-1-git-send-email-ricardo.neri-calderon@linux.intel.com>

The current default implementation of the hardlockup detector assumes that
it is implemented using perf events. However, the hardlockup detector can
be driven by other sources of non-maskable interrupts (e.g., a properly
configured timer).

Put in a separate file all the code that is specific to perf: create and
manage events, stop and start the detector. This perf-specific code is put
in the new file watchdog_hld_perf.c

The code generic code used to monitor the timers' thresholds, check
timestamps and detect hardlockups remains in watchdog_hld.c

Functions and variables are simply relocated to a new file. No functional
changes were made.

Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Andi Kleen <andi.kleen@intel.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Don Zickus <dzickus@redhat.com>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Frederic Weisbecker <frederic@kernel.org>
Cc: Babu Moger <babu.moger@oracle.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Philippe Ombredanne <pombredanne@nexb.com>
Cc: Colin Ian King <colin.king@canonical.com>
Cc: "Luis R. Rodriguez" <mcgrof@kernel.org>
Cc: "Ravi V. Shankar" <ravi.v.shankar@intel.com>
Cc: x86@kernel.org
Cc: sparclinux@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
---
 kernel/Makefile            |   3 +-
 kernel/watchdog_hld.c      | 153 --------------------------------
 kernel/watchdog_hld_perf.c | 175 +++++++++++++++++++++++++++++++++++++
 3 files changed, 177 insertions(+), 154 deletions(-)
 create mode 100644 kernel/watchdog_hld_perf.c

diff --git a/kernel/Makefile b/kernel/Makefile
index 6aa7543bcdb2..5b75e6003458 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -81,7 +81,8 @@ obj-$(CONFIG_FAIL_FUNCTION) += fail_function.o
 obj-$(CONFIG_KGDB) += debug/
 obj-$(CONFIG_DETECT_HUNG_TASK) += hung_task.o
 obj-$(CONFIG_LOCKUP_DETECTOR) += watchdog.o
-obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_hld.o
+obj-$(CONFIG_HARDLOCKUP_DETECTOR) += watchdog_hld.o
+obj-$(CONFIG_HARDLOCKUP_DETECTOR_PERF) += watchdog_hld_perf.o
 obj-$(CONFIG_SECCOMP) += seccomp.o
 obj-$(CONFIG_RELAY) += relay.o
 obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
diff --git a/kernel/watchdog_hld.c b/kernel/watchdog_hld.c
index 9724cd57307b..372db565b1b9 100644
--- a/kernel/watchdog_hld.c
+++ b/kernel/watchdog_hld.c
@@ -22,12 +22,8 @@
 
 static DEFINE_PER_CPU(bool, hard_watchdog_warn);
 static DEFINE_PER_CPU(bool, watchdog_nmi_touch);
-static DEFINE_PER_CPU(struct perf_event *, watchdog_ev);
-static DEFINE_PER_CPU(struct perf_event *, dead_event);
-static struct cpumask dead_events_mask;
 
 static unsigned long hardlockup_allcpu_dumped;
-static atomic_t watchdog_cpus = ATOMIC_INIT(0);
 
 notrace void arch_touch_nmi_watchdog(void)
 {
@@ -98,14 +94,6 @@ static inline bool watchdog_check_timestamp(void)
 }
 #endif
 
-static struct perf_event_attr wd_hw_attr = {
-	.type		= PERF_TYPE_HARDWARE,
-	.config		= PERF_COUNT_HW_CPU_CYCLES,
-	.size		= sizeof(struct perf_event_attr),
-	.pinned		= 1,
-	.disabled	= 1,
-};
-
 void inspect_for_hardlockups(struct pt_regs *regs)
 {
 	if (__this_cpu_read(watchdog_nmi_touch) == true) {
@@ -156,144 +144,3 @@ void inspect_for_hardlockups(struct pt_regs *regs)
 	return;
 }
 
-/* Callback function for perf event subsystem */
-static void watchdog_overflow_callback(struct perf_event *event,
-				       struct perf_sample_data *data,
-				       struct pt_regs *regs)
-{
-	/* Ensure the watchdog never gets throttled */
-	event->hw.interrupts = 0;
-	inspect_for_hardlockups(regs);
-}
-
-static int hardlockup_detector_event_create(void)
-{
-	unsigned int cpu = smp_processor_id();
-	struct perf_event_attr *wd_attr;
-	struct perf_event *evt;
-
-	wd_attr = &wd_hw_attr;
-	wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh);
-
-	/* Try to register using hardware perf events */
-	evt = perf_event_create_kernel_counter(wd_attr, cpu, NULL,
-					       watchdog_overflow_callback, NULL);
-	if (IS_ERR(evt)) {
-		pr_debug("Perf event create on CPU %d failed with %ld\n", cpu,
-			 PTR_ERR(evt));
-		return PTR_ERR(evt);
-	}
-	this_cpu_write(watchdog_ev, evt);
-	return 0;
-}
-
-/**
- * hardlockup_detector_perf_enable - Enable the local event
- */
-void hardlockup_detector_perf_enable(void)
-{
-	if (hardlockup_detector_event_create())
-		return;
-
-	/* use original value for check */
-	if (!atomic_fetch_inc(&watchdog_cpus))
-		pr_info("Enabled. Permanently consumes one hw-PMU counter.\n");
-
-	perf_event_enable(this_cpu_read(watchdog_ev));
-}
-
-/**
- * hardlockup_detector_perf_disable - Disable the local event
- */
-void hardlockup_detector_perf_disable(void)
-{
-	struct perf_event *event = this_cpu_read(watchdog_ev);
-
-	if (event) {
-		perf_event_disable(event);
-		this_cpu_write(watchdog_ev, NULL);
-		this_cpu_write(dead_event, event);
-		cpumask_set_cpu(smp_processor_id(), &dead_events_mask);
-		atomic_dec(&watchdog_cpus);
-	}
-}
-
-/**
- * hardlockup_detector_perf_cleanup - Cleanup disabled events and destroy them
- *
- * Called from lockup_detector_cleanup(). Serialized by the caller.
- */
-void hardlockup_detector_perf_cleanup(void)
-{
-	int cpu;
-
-	for_each_cpu(cpu, &dead_events_mask) {
-		struct perf_event *event = per_cpu(dead_event, cpu);
-
-		/*
-		 * Required because for_each_cpu() reports  unconditionally
-		 * CPU0 as set on UP kernels. Sigh.
-		 */
-		if (event)
-			perf_event_release_kernel(event);
-		per_cpu(dead_event, cpu) = NULL;
-	}
-	cpumask_clear(&dead_events_mask);
-}
-
-/**
- * hardlockup_detector_perf_stop - Globally stop watchdog events
- *
- * Special interface for x86 to handle the perf HT bug.
- */
-void __init hardlockup_detector_perf_stop(void)
-{
-	int cpu;
-
-	lockdep_assert_cpus_held();
-
-	for_each_online_cpu(cpu) {
-		struct perf_event *event = per_cpu(watchdog_ev, cpu);
-
-		if (event)
-			perf_event_disable(event);
-	}
-}
-
-/**
- * hardlockup_detector_perf_restart - Globally restart watchdog events
- *
- * Special interface for x86 to handle the perf HT bug.
- */
-void __init hardlockup_detector_perf_restart(void)
-{
-	int cpu;
-
-	lockdep_assert_cpus_held();
-
-	if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED))
-		return;
-
-	for_each_online_cpu(cpu) {
-		struct perf_event *event = per_cpu(watchdog_ev, cpu);
-
-		if (event)
-			perf_event_enable(event);
-	}
-}
-
-/**
- * hardlockup_detector_perf_init - Probe whether NMI event is available at all
- */
-int __init hardlockup_detector_perf_init(void)
-{
-	int ret = hardlockup_detector_event_create();
-
-	if (ret) {
-		pr_info("Perf NMI watchdog permanently disabled\n");
-	} else {
-		perf_event_release_kernel(this_cpu_read(watchdog_ev));
-		this_cpu_write(watchdog_ev, NULL);
-	}
-	return ret;
-}
diff --git a/kernel/watchdog_hld_perf.c b/kernel/watchdog_hld_perf.c
new file mode 100644
index 000000000000..1d06ec5a8e42
--- /dev/null
+++ b/kernel/watchdog_hld_perf.c
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Detect hard lockups on a system
+ *
+ * Copyright (C) Intel Corporation 2019
+ *
+ * Note: All of this code comes from the original perf-specific hardlockup
+ * detector.
+ */
+
+#define pr_fmt(fmt) "NMI perf watchdog: " fmt
+
+#include <linux/nmi.h>
+#include <linux/atomic.h>
+#include <linux/module.h>
+#include <linux/sched/debug.h>
+#include <linux/perf_event.h>
+#include <asm/irq_regs.h>
+
+static DEFINE_PER_CPU(struct perf_event *, watchdog_ev);
+static DEFINE_PER_CPU(struct perf_event *, dead_event);
+static struct cpumask dead_events_mask;
+
+static atomic_t watchdog_cpus = ATOMIC_INIT(0);
+
+static struct perf_event_attr wd_hw_attr = {
+	.type		= PERF_TYPE_HARDWARE,
+	.config		= PERF_COUNT_HW_CPU_CYCLES,
+	.size		= sizeof(struct perf_event_attr),
+	.pinned		= 1,
+	.disabled	= 1,
+};
+
+/* Callback function for perf event subsystem */
+static void watchdog_overflow_callback(struct perf_event *event,
+				       struct perf_sample_data *data,
+				       struct pt_regs *regs)
+{
+	/* Ensure the watchdog never gets throttled */
+	event->hw.interrupts = 0;
+	inspect_for_hardlockups(regs);
+}
+
+static int hardlockup_detector_event_create(void)
+{
+	unsigned int cpu = smp_processor_id();
+	struct perf_event_attr *wd_attr;
+	struct perf_event *evt;
+
+	wd_attr = &wd_hw_attr;
+	wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh);
+
+	/* Try to register using hardware perf events */
+	evt = perf_event_create_kernel_counter(wd_attr, cpu, NULL,
+					       watchdog_overflow_callback, NULL);
+	if (IS_ERR(evt)) {
+		pr_debug("Perf event create on CPU %d failed with %ld\n", cpu,
+			 PTR_ERR(evt));
+		return PTR_ERR(evt);
+	}
+	this_cpu_write(watchdog_ev, evt);
+	return 0;
+}
+
+/**
+ * hardlockup_detector_perf_enable - Enable the local event
+ */
+void hardlockup_detector_perf_enable(void)
+{
+	if (hardlockup_detector_event_create())
+		return;
+
+	/* use original value for check */
+	if (!atomic_fetch_inc(&watchdog_cpus))
+		pr_info("Enabled. Permanently consumes one hw-PMU counter.\n");
+
+	perf_event_enable(this_cpu_read(watchdog_ev));
+}
+
+/**
+ * hardlockup_detector_perf_disable - Disable the local event
+ */
+void hardlockup_detector_perf_disable(void)
+{
+	struct perf_event *event = this_cpu_read(watchdog_ev);
+
+	if (event) {
+		perf_event_disable(event);
+		this_cpu_write(watchdog_ev, NULL);
+		this_cpu_write(dead_event, event);
+		cpumask_set_cpu(smp_processor_id(), &dead_events_mask);
+		atomic_dec(&watchdog_cpus);
+	}
+}
+
+/**
+ * hardlockup_detector_perf_cleanup - Cleanup disabled events and destroy them
+ *
+ * Called from lockup_detector_cleanup(). Serialized by the caller.
+ */
+void hardlockup_detector_perf_cleanup(void)
+{
+	int cpu;
+
+	for_each_cpu(cpu, &dead_events_mask) {
+		struct perf_event *event = per_cpu(dead_event, cpu);
+
+		/*
+		 * Required because for_each_cpu() reports  unconditionally
+		 * CPU0 as set on UP kernels. Sigh.
+		 */
+		if (event)
+			perf_event_release_kernel(event);
+		per_cpu(dead_event, cpu) = NULL;
+	}
+	cpumask_clear(&dead_events_mask);
+}
+
+/**
+ * hardlockup_detector_perf_stop - Globally stop watchdog events
+ *
+ * Special interface for x86 to handle the perf HT bug.
+ */
+void __init hardlockup_detector_perf_stop(void)
+{
+	int cpu;
+
+	lockdep_assert_cpus_held();
+
+	for_each_online_cpu(cpu) {
+		struct perf_event *event = per_cpu(watchdog_ev, cpu);
+
+		if (event)
+			perf_event_disable(event);
+	}
+}
+
+/**
+ * hardlockup_detector_perf_restart - Globally restart watchdog events
+ *
+ * Special interface for x86 to handle the perf HT bug.
+ */
+void __init hardlockup_detector_perf_restart(void)
+{
+	int cpu;
+
+	lockdep_assert_cpus_held();
+
+	if (!(watchdog_enabled & NMI_WATCHDOG_ENABLED))
+		return;
+
+	for_each_online_cpu(cpu) {
+		struct perf_event *event = per_cpu(watchdog_ev, cpu);
+
+		if (event)
+			perf_event_enable(event);
+	}
+}
+
+/**
+ * hardlockup_detector_perf_init - Probe whether NMI event is available at all
+ */
+int __init hardlockup_detector_perf_init(void)
+{
+	int ret = hardlockup_detector_event_create();
+
+	if (ret) {
+		pr_info("Perf NMI watchdog permanently disabled\n");
+	} else {
+		perf_event_release_kernel(this_cpu_read(watchdog_ev));
+		this_cpu_write(watchdog_ev, NULL);
+	}
+	return ret;
+}
+
-- 
2.17.1


^ permalink raw reply related

* DMA & POWER8
From: Илья Кузнецов @ 2019-02-27 15:57 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: a.fomichev

We're trying to use Slave-DMA API of the DMA Engine in the linux kernel on
POWER8 OpenPOWER platform. And we discovered that dma_request_channel() always fails.
Does it mean that Turismo hardware does not support Slave-DMA? Or DMA
subsystem in the linux kernel needs to be fixed, doesn't it?

^ permalink raw reply

* Re: [PATCH v2] powerpc/powernv/idle: Restore IAMR after idle
From: Nicholas Piggin @ 2019-02-27 14:53 UTC (permalink / raw)
  To: linuxppc-dev, Russell Currey
In-Reply-To: <20190208111103.4901-1-ruscur@russell.cc>

Russell Currey's on February 8, 2019 9:11 pm:
> Without restoring the IAMR after idle, execution prevention on POWER9
> with Radix MMU is overwritten and the kernel can freely execute userspace without
> faulting.
> 
> This is necessary when returning from any stop state that modifies user
> state, as well as hypervisor state.
> 
> To test how this fails without this patch, load the lkdtm driver and
> do the following:
> 
>    echo EXEC_USERSPACE > /sys/kernel/debug/provoke-crash/DIRECT
> 
> which won't fault, then boot the kernel with powersave=off, where it
> will fault.  Applying this patch will fix this.
> 
> Fixes: 3b10d0095a1e ("powerpc/mm/radix: Prevent kernel execution of user
> space")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Russell Currey <ruscur@russell.cc>
> ---
> Since v1:
>       - no longer use paca to save IAMR, instead use _DAR (thanks mpe)
>       - remove isync and pnv_wakeup_noloss section (thanks Nick)

Thanks for that, looks good.

Reviewed-by: Nicholas Piggin <npiggin@gmail.com>


^ permalink raw reply

* [PATCH v8 2/4] mm: Update get_user_pages_longterm to migrate pages allocated from CMA region
From: Aneesh Kumar K.V @ 2019-02-27 14:47 UTC (permalink / raw)
  To: akpm, Michal Hocko, Alexey Kardashevskiy, David Gibson,
	Andrea Arcangeli, mpe
  Cc: linux-mm, linuxppc-dev, linux-kernel, Aneesh Kumar K.V
In-Reply-To: <20190227144736.5872-1-aneesh.kumar@linux.ibm.com>

This patch updates get_user_pages_longterm to migrate pages allocated out
of CMA region. This makes sure that we don't keep non-movable pages (due to page
reference count) in the CMA area.

This will be used by ppc64 in a later patch to avoid pinning pages in the CMA
region. ppc64 uses CMA region for allocation of the hardware page table (hash page
table) and not able to migrate pages out of CMA region results in page table
allocation failures.

One case where we hit this easy is when a guest using a VFIO passthrough device.
VFIO locks all the guest's memory and if the guest memory is backed by CMA
region, it becomes unmovable resulting in fragmenting the CMA and possibly
preventing other guests from allocation a large enough hash page table.

NOTE: We allocate the new page without using __GFP_THISNODE

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
 include/linux/hugetlb.h |   2 +
 include/linux/mm.h      |   3 +-
 mm/gup.c                | 200 +++++++++++++++++++++++++++++++++++-----
 mm/hugetlb.c            |   4 +-
 4 files changed, 182 insertions(+), 27 deletions(-)

diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 087fd5f48c91..1eed0cdaec0e 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -371,6 +371,8 @@ struct page *alloc_huge_page_nodemask(struct hstate *h, int preferred_nid,
 				nodemask_t *nmask);
 struct page *alloc_huge_page_vma(struct hstate *h, struct vm_area_struct *vma,
 				unsigned long address);
+struct page *alloc_migrate_huge_page(struct hstate *h, gfp_t gfp_mask,
+				     int nid, nodemask_t *nmask);
 int huge_add_to_page_cache(struct page *page, struct address_space *mapping,
 			pgoff_t idx);
 
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 80bb6408fe73..20ec56f8e2bb 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1536,7 +1536,8 @@ long get_user_pages_locked(unsigned long start, unsigned long nr_pages,
 		    unsigned int gup_flags, struct page **pages, int *locked);
 long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages,
 		    struct page **pages, unsigned int gup_flags);
-#ifdef CONFIG_FS_DAX
+
+#if defined(CONFIG_FS_DAX) || defined(CONFIG_CMA)
 long get_user_pages_longterm(unsigned long start, unsigned long nr_pages,
 			    unsigned int gup_flags, struct page **pages,
 			    struct vm_area_struct **vmas);
diff --git a/mm/gup.c b/mm/gup.c
index 75029649baca..22291db50013 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -13,6 +13,9 @@
 #include <linux/sched/signal.h>
 #include <linux/rwsem.h>
 #include <linux/hugetlb.h>
+#include <linux/migrate.h>
+#include <linux/mm_inline.h>
+#include <linux/sched/mm.h>
 
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
@@ -1126,7 +1129,167 @@ long get_user_pages(unsigned long start, unsigned long nr_pages,
 }
 EXPORT_SYMBOL(get_user_pages);
 
+#if defined(CONFIG_FS_DAX) || defined (CONFIG_CMA)
+
 #ifdef CONFIG_FS_DAX
+static bool check_dax_vmas(struct vm_area_struct **vmas, long nr_pages)
+{
+	long i;
+	struct vm_area_struct *vma_prev = NULL;
+
+	for (i = 0; i < nr_pages; i++) {
+		struct vm_area_struct *vma = vmas[i];
+
+		if (vma == vma_prev)
+			continue;
+
+		vma_prev = vma;
+
+		if (vma_is_fsdax(vma))
+			return true;
+	}
+	return false;
+}
+#else
+static inline bool check_dax_vmas(struct vm_area_struct **vmas, long nr_pages)
+{
+	return false;
+}
+#endif
+
+#ifdef CONFIG_CMA
+static struct page *new_non_cma_page(struct page *page, unsigned long private)
+{
+	/*
+	 * We want to make sure we allocate the new page from the same node
+	 * as the source page.
+	 */
+	int nid = page_to_nid(page);
+	/*
+	 * Trying to allocate a page for migration. Ignore allocation
+	 * failure warnings. We don't force __GFP_THISNODE here because
+	 * this node here is the node where we have CMA reservation and
+	 * in some case these nodes will have really less non movable
+	 * allocation memory.
+	 */
+	gfp_t gfp_mask = GFP_USER | __GFP_NOWARN;
+
+	if (PageHighMem(page))
+		gfp_mask |= __GFP_HIGHMEM;
+
+#ifdef CONFIG_HUGETLB_PAGE
+	if (PageHuge(page)) {
+		struct hstate *h = page_hstate(page);
+		/*
+		 * We don't want to dequeue from the pool because pool pages will
+		 * mostly be from the CMA region.
+		 */
+		return alloc_migrate_huge_page(h, gfp_mask, nid, NULL);
+	}
+#endif
+	if (PageTransHuge(page)) {
+		struct page *thp;
+		/*
+		 * ignore allocation failure warnings
+		 */
+		gfp_t thp_gfpmask = GFP_TRANSHUGE | __GFP_NOWARN;
+
+		/*
+		 * Remove the movable mask so that we don't allocate from
+		 * CMA area again.
+		 */
+		thp_gfpmask &= ~__GFP_MOVABLE;
+		thp = __alloc_pages_node(nid, thp_gfpmask, HPAGE_PMD_ORDER);
+		if (!thp)
+			return NULL;
+		prep_transhuge_page(thp);
+		return thp;
+	}
+
+	return __alloc_pages_node(nid, gfp_mask, 0);
+}
+
+static long check_and_migrate_cma_pages(unsigned long start, long nr_pages,
+					unsigned int gup_flags,
+					struct page **pages,
+					struct vm_area_struct **vmas)
+{
+	long i;
+	bool drain_allow = true;
+	bool migrate_allow = true;
+	LIST_HEAD(cma_page_list);
+
+check_again:
+	for (i = 0; i < nr_pages; i++) {
+		/*
+		 * If we get a page from the CMA zone, since we are going to
+		 * be pinning these entries, we might as well move them out
+		 * of the CMA zone if possible.
+		 */
+		if (is_migrate_cma_page(pages[i])) {
+
+			struct page *head = compound_head(pages[i]);
+
+			if (PageHuge(head)) {
+				isolate_huge_page(head, &cma_page_list);
+			} else {
+				if (!PageLRU(head) && drain_allow) {
+					lru_add_drain_all();
+					drain_allow = false;
+				}
+
+				if (!isolate_lru_page(head)) {
+					list_add_tail(&head->lru, &cma_page_list);
+					mod_node_page_state(page_pgdat(head),
+							    NR_ISOLATED_ANON +
+							    page_is_file_cache(head),
+							    hpage_nr_pages(head));
+				}
+			}
+		}
+	}
+
+	if (!list_empty(&cma_page_list)) {
+		/*
+		 * drop the above get_user_pages reference.
+		 */
+		for (i = 0; i < nr_pages; i++)
+			put_page(pages[i]);
+
+		if (migrate_pages(&cma_page_list, new_non_cma_page,
+				  NULL, 0, MIGRATE_SYNC, MR_CONTIG_RANGE)) {
+			/*
+			 * some of the pages failed migration. Do get_user_pages
+			 * without migration.
+			 */
+			migrate_allow = false;
+
+			if (!list_empty(&cma_page_list))
+				putback_movable_pages(&cma_page_list);
+		}
+		/*
+		 * We did migrate all the pages, Try to get the page references again
+		 * migrating any new CMA pages which we failed to isolate earlier.
+		 */
+		nr_pages = get_user_pages(start, nr_pages, gup_flags, pages, vmas);
+		if ((nr_pages > 0) && migrate_allow) {
+			drain_allow = true;
+			goto check_again;
+		}
+	}
+
+	return nr_pages;
+}
+#else
+static inline long check_and_migrate_cma_pages(unsigned long start, long nr_pages,
+					       unsigned int gup_flags,
+					       struct page **pages,
+					       struct vm_area_struct **vmas)
+{
+	return nr_pages;
+}
+#endif
+
 /*
  * This is the same as get_user_pages() in that it assumes we are
  * operating on the current task's mm, but it goes further to validate
@@ -1140,11 +1303,11 @@ EXPORT_SYMBOL(get_user_pages);
  * Contrast this to iov_iter_get_pages() usages which are transient.
  */
 long get_user_pages_longterm(unsigned long start, unsigned long nr_pages,
-		unsigned int gup_flags, struct page **pages,
-		struct vm_area_struct **vmas_arg)
+			     unsigned int gup_flags, struct page **pages,
+			     struct vm_area_struct **vmas_arg)
 {
 	struct vm_area_struct **vmas = vmas_arg;
-	struct vm_area_struct *vma_prev = NULL;
+	unsigned long flags;
 	long rc, i;
 
 	if (!pages)
@@ -1157,31 +1320,20 @@ long get_user_pages_longterm(unsigned long start, unsigned long nr_pages,
 			return -ENOMEM;
 	}
 
+	flags = memalloc_nocma_save();
 	rc = get_user_pages(start, nr_pages, gup_flags, pages, vmas);
+	memalloc_nocma_restore(flags);
+	if (rc < 0)
+		goto out;
 
-	for (i = 0; i < rc; i++) {
-		struct vm_area_struct *vma = vmas[i];
-
-		if (vma == vma_prev)
-			continue;
-
-		vma_prev = vma;
-
-		if (vma_is_fsdax(vma))
-			break;
-	}
-
-	/*
-	 * Either get_user_pages() failed, or the vma validation
-	 * succeeded, in either case we don't need to put_page() before
-	 * returning.
-	 */
-	if (i >= rc)
+	if (check_dax_vmas(vmas, rc)) {
+		for (i = 0; i < rc; i++)
+			put_page(pages[i]);
+		rc = -EOPNOTSUPP;
 		goto out;
+	}
 
-	for (i = 0; i < rc; i++)
-		put_page(pages[i]);
-	rc = -EOPNOTSUPP;
+	rc = check_and_migrate_cma_pages(start, rc, gup_flags, pages, vmas);
 out:
 	if (vmas != vmas_arg)
 		kfree(vmas);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index afef61656c1e..c80f0c16a226 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1586,8 +1586,8 @@ static struct page *alloc_surplus_huge_page(struct hstate *h, gfp_t gfp_mask,
 	return page;
 }
 
-static struct page *alloc_migrate_huge_page(struct hstate *h, gfp_t gfp_mask,
-		int nid, nodemask_t *nmask)
+struct page *alloc_migrate_huge_page(struct hstate *h, gfp_t gfp_mask,
+				     int nid, nodemask_t *nmask)
 {
 	struct page *page;
 
-- 
2.20.1


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox