* Re: [PATCH v5 1/4] resource: Move reparent_resources() to kernel/resource.c and make it public
From: kbuild test robot @ 2018-06-12 3:55 UTC (permalink / raw)
To: Baoquan He
Cc: kbuild-all, linux-kernel, akpm, robh+dt, dan.j.williams,
nicolas.pitre, josh, fengguang.wu, bp, patrik.r.jakobsson,
airlied, kys, haiyangz, sthemmin, dmitry.torokhov, frowand.list,
keith.busch, jonathan.derrick, lorenzo.pieralisi, bhelgaas, tglx,
brijesh.singh, jglisse, thomas.lendacky, gregkh, baiyaowei,
richard.weiyang, devel, linux-input, linux-nvdimm, devicetree,
linux-pci, ebiederm, vgoyal, dyoung, yinghai, kexec, monstr,
davem, chris, jcmvbkbc, gustavo, maarten.lankhorst, seanpaul,
linux-parisc, linuxppc-dev, Baoquan He, Benjamin Herrenschmidt,
Paul Mackerras, Michael Ellerman
In-Reply-To: <20180612032831.29747-2-bhe@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 2814 bytes --]
Hi Baoquan,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on v4.17 next-20180608]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180612-113600
config: i386-tinyconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
Note: the linux-review/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180612-113600 HEAD 5545e79eef6387857faf41cdffa7be6b1f5d4efe builds fine.
It only hurts bisectibility.
All errors (new ones prefixed by >>):
>> kernel/resource.c:990:12: error: static declaration of 'reparent_resources' follows non-static declaration
static int reparent_resources(struct resource *parent,
^~~~~~~~~~~~~~~~~~
In file included from kernel/resource.c:14:0:
include/linux/ioport.h:195:5: note: previous declaration of 'reparent_resources' was here
int reparent_resources(struct resource *parent, struct resource *res);
^~~~~~~~~~~~~~~~~~
kernel/resource.c:990:12: warning: 'reparent_resources' defined but not used [-Wunused-function]
static int reparent_resources(struct resource *parent,
^~~~~~~~~~~~~~~~~~
vim +/reparent_resources +990 kernel/resource.c
985
986 /*
987 * Reparent resource children of pr that conflict with res
988 * under res, and make res replace those children.
989 */
> 990 static int reparent_resources(struct resource *parent,
991 struct resource *res)
992 {
993 struct resource *p, **pp;
994 struct resource **firstpp = NULL;
995
996 for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
997 if (p->end < res->start)
998 continue;
999 if (res->end < p->start)
1000 break;
1001 if (p->start < res->start || p->end > res->end)
1002 return -1; /* not completely contained */
1003 if (firstpp == NULL)
1004 firstpp = pp;
1005 }
1006 if (firstpp == NULL)
1007 return -1; /* didn't find any conflicting entries? */
1008 res->parent = parent;
1009 res->child = *firstpp;
1010 res->sibling = *pp;
1011 *firstpp = res;
1012 *pp = NULL;
1013 for (p = res->child; p != NULL; p = p->sibling) {
1014 p->parent = res;
1015 pr_debug("PCI: Reparented %s %pR under %s\n",
1016 p->name, p, res->name);
1017 }
1018 return 0;
1019 }
1020 EXPORT_SYMBOL(reparent_resources);
1021
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 6347 bytes --]
^ permalink raw reply
* Re: [PATCH v5 2/4] resource: Use list_head to link sibling resource
From: kbuild test robot @ 2018-06-12 4:37 UTC (permalink / raw)
To: Baoquan He
Cc: kbuild-all, linux-kernel, akpm, robh+dt, dan.j.williams,
nicolas.pitre, josh, fengguang.wu, bp, brijesh.singh, devicetree,
airlied, linux-pci, richard.weiyang, keith.busch, jcmvbkbc,
baiyaowei, frowand.list, lorenzo.pieralisi, sthemmin, Baoquan He,
linux-nvdimm, patrik.r.jakobsson, linux-input, gustavo, dyoung,
vgoyal, thomas.lendacky, haiyangz, maarten.lankhorst, jglisse,
seanpaul, bhelgaas, tglx, yinghai, jonathan.derrick, chris,
monstr, linux-parisc, gregkh, dmitry.torokhov, kexec, ebiederm,
devel, linuxppc-dev, davem
In-Reply-To: <20180612032831.29747-3-bhe@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 4534 bytes --]
Hi Baoquan,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on v4.17 next-20180608]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180612-113600
config: i386-tinyconfig (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
kernel/resource.c: In function 'reparent_resources':
>> kernel/resource.c:1005:26: error: passing argument 2 of 'list_add' from incompatible pointer type [-Werror=incompatible-pointer-types]
list_add(&res->sibling, &p->sibling.prev);
^
In file included from include/linux/ioport.h:15:0,
from kernel/resource.c:14:
include/linux/list.h:77:20: note: expected 'struct list_head *' but argument is of type 'struct list_head **'
static inline void list_add(struct list_head *new, struct list_head *head)
^~~~~~~~
In file included from include/linux/list.h:9:0,
from include/linux/ioport.h:15,
from kernel/resource.c:14:
>> kernel/resource.c:1013:26: error: 'new' undeclared (first use in this function); did you mean 'net'?
list_for_each_entry(p, &new->child, sibling) {
^
include/linux/kernel.h:963:26: note: in definition of macro 'container_of'
void *__mptr = (void *)(ptr); \
^~~
include/linux/list.h:377:2: note: in expansion of macro 'list_entry'
list_entry((ptr)->next, type, member)
^~~~~~~~~~
include/linux/list.h:464:13: note: in expansion of macro 'list_first_entry'
for (pos = list_first_entry(head, typeof(*pos), member); \
^~~~~~~~~~~~~~~~
kernel/resource.c:1013:2: note: in expansion of macro 'list_for_each_entry'
list_for_each_entry(p, &new->child, sibling) {
^~~~~~~~~~~~~~~~~~~
kernel/resource.c:1013:26: note: each undeclared identifier is reported only once for each function it appears in
list_for_each_entry(p, &new->child, sibling) {
^
include/linux/kernel.h:963:26: note: in definition of macro 'container_of'
void *__mptr = (void *)(ptr); \
^~~
include/linux/list.h:377:2: note: in expansion of macro 'list_entry'
list_entry((ptr)->next, type, member)
^~~~~~~~~~
include/linux/list.h:464:13: note: in expansion of macro 'list_first_entry'
for (pos = list_first_entry(head, typeof(*pos), member); \
^~~~~~~~~~~~~~~~
kernel/resource.c:1013:2: note: in expansion of macro 'list_for_each_entry'
list_for_each_entry(p, &new->child, sibling) {
^~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +/list_add +1005 kernel/resource.c
983
984 /*
985 * Reparent resource children of pr that conflict with res
986 * under res, and make res replace those children.
987 */
988 int reparent_resources(struct resource *parent, struct resource *res)
989 {
990 struct resource *p, *first = NULL;
991
992 list_for_each_entry(p, &parent->child, sibling) {
993 if (p->end < res->start)
994 continue;
995 if (res->end < p->start)
996 break;
997 if (p->start < res->start || p->end > res->end)
998 return -1; /* not completely contained */
999 if (first == NULL)
1000 first = p;
1001 }
1002 if (first == NULL)
1003 return -1; /* didn't find any conflicting entries? */
1004 res->parent = parent;
> 1005 list_add(&res->sibling, &p->sibling.prev);
1006 INIT_LIST_HEAD(&res->child);
1007
1008 /*
1009 * From first to p's previous sibling, they all fall into
1010 * res's region, change them as res's children.
1011 */
1012 list_cut_position(&res->child, first->sibling.prev, res->sibling.prev);
> 1013 list_for_each_entry(p, &new->child, sibling) {
1014 p->parent = new;
1015 pr_debug("PCI: Reparented %s %pR under %s\n",
1016 p->name, p, res->name);
1017 }
1018 return 0;
1019 }
1020 EXPORT_SYMBOL(reparent_resources);
1021
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 6347 bytes --]
^ permalink raw reply
* Re: [PATCH] misc: ocxl: Change return type for fault handler
From: Andrew Donnellan @ 2018-06-12 4:39 UTC (permalink / raw)
To: Souptick Joarder, willy, fbarrat, arnd, gregkh
Cc: brajeswar.linux, linuxppc-dev, linux-kernel, sabyasachi.linux
In-Reply-To: <20180611202904.GA25538@jordon-HP-15-Notebook-PC>
On 12/06/18 06:29, Souptick Joarder wrote:
> Use new return type vm_fault_t for fault handler. For
> now, this is just documenting that the function returns
> a VM_FAULT value rather than an errno. Once all instances
> are converted, vm_fault_t will become a distinct type.
>
> Ref-> commit 1c8f422059ae ("mm: change return type to vm_fault_t")
>
> There is an existing bug when vm_insert_pfn() can return
> ENOMEM which was ignored and VM_FAULT_NOPAGE returned as
> default. The new inline vmf_insert_pfn() has removed
> this inefficiency by returning correct vm_fault_ type.
>
> Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
Looks okay to me
Acked-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
> ---
> drivers/misc/ocxl/context.c | 22 +++++++++++-----------
> drivers/misc/ocxl/sysfs.c | 5 ++---
> 2 files changed, 13 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/misc/ocxl/context.c b/drivers/misc/ocxl/context.c
> index 909e880..98daf91 100644
> --- a/drivers/misc/ocxl/context.c
> +++ b/drivers/misc/ocxl/context.c
> @@ -83,7 +83,7 @@ int ocxl_context_attach(struct ocxl_context *ctx, u64 amr)
> return rc;
> }
>
> -static int map_afu_irq(struct vm_area_struct *vma, unsigned long address,
> +static vm_fault_t map_afu_irq(struct vm_area_struct *vma, unsigned long address,
> u64 offset, struct ocxl_context *ctx)
> {
> u64 trigger_addr;
> @@ -92,15 +92,15 @@ static int map_afu_irq(struct vm_area_struct *vma, unsigned long address,
> if (!trigger_addr)
> return VM_FAULT_SIGBUS;
>
> - vm_insert_pfn(vma, address, trigger_addr >> PAGE_SHIFT);
> - return VM_FAULT_NOPAGE;
> + return vmf_insert_pfn(vma, address, trigger_addr >> PAGE_SHIFT);
> }
>
> -static int map_pp_mmio(struct vm_area_struct *vma, unsigned long address,
> +static vm_fault_t map_pp_mmio(struct vm_area_struct *vma, unsigned long address,
> u64 offset, struct ocxl_context *ctx)
> {
> u64 pp_mmio_addr;
> int pasid_off;
> + vm_fault_t ret;
>
> if (offset >= ctx->afu->config.pp_mmio_stride)
> return VM_FAULT_SIGBUS;
> @@ -118,27 +118,27 @@ static int map_pp_mmio(struct vm_area_struct *vma, unsigned long address,
> pasid_off * ctx->afu->config.pp_mmio_stride +
> offset;
>
> - vm_insert_pfn(vma, address, pp_mmio_addr >> PAGE_SHIFT);
> + ret = vmf_insert_pfn(vma, address, pp_mmio_addr >> PAGE_SHIFT);
> mutex_unlock(&ctx->status_mutex);
> - return VM_FAULT_NOPAGE;
> + return ret;
> }
>
> -static int ocxl_mmap_fault(struct vm_fault *vmf)
> +static vm_fault_t ocxl_mmap_fault(struct vm_fault *vmf)
> {
> struct vm_area_struct *vma = vmf->vma;
> struct ocxl_context *ctx = vma->vm_file->private_data;
> u64 offset;
> - int rc;
> + vm_fault_t ret;
>
> offset = vmf->pgoff << PAGE_SHIFT;
> pr_debug("%s: pasid %d address 0x%lx offset 0x%llx\n", __func__,
> ctx->pasid, vmf->address, offset);
>
> if (offset < ctx->afu->irq_base_offset)
> - rc = map_pp_mmio(vma, vmf->address, offset, ctx);
> + ret = map_pp_mmio(vma, vmf->address, offset, ctx);
> else
> - rc = map_afu_irq(vma, vmf->address, offset, ctx);
> - return rc;
> + ret = map_afu_irq(vma, vmf->address, offset, ctx);
> + return ret;
> }
>
> static const struct vm_operations_struct ocxl_vmops = {
> diff --git a/drivers/misc/ocxl/sysfs.c b/drivers/misc/ocxl/sysfs.c
> index d9753a1..0ab1fd1 100644
> --- a/drivers/misc/ocxl/sysfs.c
> +++ b/drivers/misc/ocxl/sysfs.c
> @@ -64,7 +64,7 @@ static ssize_t global_mmio_read(struct file *filp, struct kobject *kobj,
> return count;
> }
>
> -static int global_mmio_fault(struct vm_fault *vmf)
> +static vm_fault_t global_mmio_fault(struct vm_fault *vmf)
> {
> struct vm_area_struct *vma = vmf->vma;
> struct ocxl_afu *afu = vma->vm_private_data;
> @@ -75,8 +75,7 @@ static int global_mmio_fault(struct vm_fault *vmf)
>
> offset = vmf->pgoff;
> offset += (afu->global_mmio_start >> PAGE_SHIFT);
> - vm_insert_pfn(vma, vmf->address, offset);
> - return VM_FAULT_NOPAGE;
> + return vmf_insert_pfn(vma, vmf->address, offset);
> }
>
> static const struct vm_operations_struct global_mmio_vmops = {
>
--
Andrew Donnellan OzLabs, ADL Canberra
andrew.donnellan@au1.ibm.com IBM Australia Limited
^ permalink raw reply
* Re: [PATCH v5 2/4] resource: Use list_head to link sibling resource
From: kbuild test robot @ 2018-06-12 4:49 UTC (permalink / raw)
To: Baoquan He
Cc: kbuild-all, linux-kernel, akpm, robh+dt, dan.j.williams,
nicolas.pitre, josh, fengguang.wu, bp, brijesh.singh, devicetree,
airlied, linux-pci, richard.weiyang, keith.busch, jcmvbkbc,
baiyaowei, frowand.list, lorenzo.pieralisi, sthemmin, Baoquan He,
linux-nvdimm, patrik.r.jakobsson, linux-input, gustavo, dyoung,
vgoyal, thomas.lendacky, haiyangz, maarten.lankhorst, jglisse,
seanpaul, bhelgaas, tglx, yinghai, jonathan.derrick, chris,
monstr, linux-parisc, gregkh, dmitry.torokhov, kexec, ebiederm,
devel, linuxppc-dev, davem
In-Reply-To: <20180612032831.29747-3-bhe@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 4571 bytes --]
Hi Baoquan,
I love your patch! Perhaps something to improve:
[auto build test WARNING on linus/master]
[also build test WARNING on v4.17 next-20180608]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180612-113600
config: x86_64-randconfig-x011-201823 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
kernel/resource.c: In function 'reparent_resources':
kernel/resource.c:1005:26: error: passing argument 2 of 'list_add' from incompatible pointer type [-Werror=incompatible-pointer-types]
list_add(&res->sibling, &p->sibling.prev);
^
In file included from include/linux/ioport.h:15:0,
from kernel/resource.c:14:
include/linux/list.h:77:20: note: expected 'struct list_head *' but argument is of type 'struct list_head **'
static inline void list_add(struct list_head *new, struct list_head *head)
^~~~~~~~
In file included from include/linux/list.h:9:0,
from include/linux/ioport.h:15,
from kernel/resource.c:14:
kernel/resource.c:1013:26: error: 'new' undeclared (first use in this function); did you mean 'net'?
list_for_each_entry(p, &new->child, sibling) {
^
include/linux/kernel.h:963:26: note: in definition of macro 'container_of'
void *__mptr = (void *)(ptr); \
^~~
include/linux/list.h:377:2: note: in expansion of macro 'list_entry'
list_entry((ptr)->next, type, member)
^~~~~~~~~~
include/linux/list.h:464:13: note: in expansion of macro 'list_first_entry'
for (pos = list_first_entry(head, typeof(*pos), member); \
^~~~~~~~~~~~~~~~
>> kernel/resource.c:1013:2: note: in expansion of macro 'list_for_each_entry'
list_for_each_entry(p, &new->child, sibling) {
^~~~~~~~~~~~~~~~~~~
kernel/resource.c:1013:26: note: each undeclared identifier is reported only once for each function it appears in
list_for_each_entry(p, &new->child, sibling) {
^
include/linux/kernel.h:963:26: note: in definition of macro 'container_of'
void *__mptr = (void *)(ptr); \
^~~
include/linux/list.h:377:2: note: in expansion of macro 'list_entry'
list_entry((ptr)->next, type, member)
^~~~~~~~~~
include/linux/list.h:464:13: note: in expansion of macro 'list_first_entry'
for (pos = list_first_entry(head, typeof(*pos), member); \
^~~~~~~~~~~~~~~~
>> kernel/resource.c:1013:2: note: in expansion of macro 'list_for_each_entry'
list_for_each_entry(p, &new->child, sibling) {
^~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +/list_for_each_entry +1013 kernel/resource.c
983
984 /*
985 * Reparent resource children of pr that conflict with res
986 * under res, and make res replace those children.
987 */
988 int reparent_resources(struct resource *parent, struct resource *res)
989 {
990 struct resource *p, *first = NULL;
991
992 list_for_each_entry(p, &parent->child, sibling) {
993 if (p->end < res->start)
994 continue;
995 if (res->end < p->start)
996 break;
997 if (p->start < res->start || p->end > res->end)
998 return -1; /* not completely contained */
999 if (first == NULL)
1000 first = p;
1001 }
1002 if (first == NULL)
1003 return -1; /* didn't find any conflicting entries? */
1004 res->parent = parent;
1005 list_add(&res->sibling, &p->sibling.prev);
1006 INIT_LIST_HEAD(&res->child);
1007
1008 /*
1009 * From first to p's previous sibling, they all fall into
1010 * res's region, change them as res's children.
1011 */
1012 list_cut_position(&res->child, first->sibling.prev, res->sibling.prev);
> 1013 list_for_each_entry(p, &new->child, sibling) {
1014 p->parent = new;
1015 pr_debug("PCI: Reparented %s %pR under %s\n",
1016 p->name, p, res->name);
1017 }
1018 return 0;
1019 }
1020 EXPORT_SYMBOL(reparent_resources);
1021
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 20640 bytes --]
^ permalink raw reply
* Re: [PATCH kernel 6/6] powerpc/powernv/ioda: Allocate indirect TCE levels on demand
From: David Gibson @ 2018-06-12 4:17 UTC (permalink / raw)
To: Alexey Kardashevskiy
Cc: linuxppc-dev, kvm-ppc, kvm, Alex Williamson,
Benjamin Herrenschmidt
In-Reply-To: <20180608054633.18659-7-aik@ozlabs.ru>
[-- Attachment #1: Type: text/plain, Size: 14540 bytes --]
On Fri, Jun 08, 2018 at 03:46:33PM +1000, Alexey Kardashevskiy wrote:
> At the moment we allocate the entire TCE table, twice (hardware part and
> userspace translation cache). This normally works as we normally have
> contigous memory and the guest will map entire RAM for 64bit DMA.
>
> However if we have sparse RAM (one example is a memory device), then
> we will allocate TCEs which will never be used as the guest only maps
> actual memory for DMA. If it is a single level TCE table, there is nothing
> we can really do but if it a multilevel table, we can skip allocating
> TCEs we know we won't need.
>
> This adds ability to allocate only first level, saving memory.
>
> This changes iommu_table::free() to avoid allocating of an extra level;
> iommu_table::set() will do this when needed.
>
> This adds @alloc parameter to iommu_table::exchange() to tell the callback
> if it can allocate an extra level; the flag is set to "false" for
> the realmode KVM handlers of H_PUT_TCE hcalls and the callback returns
> H_TOO_HARD.
>
> This still requires the entire table to be counted in mm::locked_vm.
>
> To be conservative, this only does on-demand allocation when
> the usespace cache table is requested which is the case of VFIO.
>
> The example math for a system replicating a powernv setup with NVLink2
> in a guest:
> 16GB RAM mapped at 0x0
> 128GB GPU RAM window (16GB of actual RAM) mapped at 0x244000000000
>
> the table to cover that all with 64K pages takes:
> (((0x244000000000 + 0x2000000000) >> 16)*8)>>20 = 4556MB
>
> If we allocate only necessary TCE levels, we will only need:
> (((0x400000000 + 0x400000000) >> 16)*8)>>20 = 4MB (plus some for indirect
> levels).
>
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
> arch/powerpc/include/asm/iommu.h | 7 ++-
> arch/powerpc/platforms/powernv/pci.h | 6 ++-
> arch/powerpc/kvm/book3s_64_vio_hv.c | 4 +-
> arch/powerpc/platforms/powernv/pci-ioda-tce.c | 69 ++++++++++++++++++++-------
> arch/powerpc/platforms/powernv/pci-ioda.c | 8 ++--
> drivers/vfio/vfio_iommu_spapr_tce.c | 2 +-
> 6 files changed, 69 insertions(+), 27 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
> index 4bdcf22..daa3ee5 100644
> --- a/arch/powerpc/include/asm/iommu.h
> +++ b/arch/powerpc/include/asm/iommu.h
> @@ -70,7 +70,7 @@ struct iommu_table_ops {
> unsigned long *hpa,
> enum dma_data_direction *direction);
>
> - __be64 *(*useraddrptr)(struct iommu_table *tbl, long index);
> + __be64 *(*useraddrptr)(struct iommu_table *tbl, long index, bool alloc);
> #endif
> void (*clear)(struct iommu_table *tbl,
> long index, long npages);
> @@ -122,10 +122,13 @@ struct iommu_table {
> __be64 *it_userspace; /* userspace view of the table */
> struct iommu_table_ops *it_ops;
> struct kref it_kref;
> + int it_nid;
> };
>
> +#define IOMMU_TABLE_USERSPACE_ENTRY_RM(tbl, entry) \
> + ((tbl)->it_ops->useraddrptr((tbl), (entry), false))
Is real mode really the only case where you want to inhibit new
allocations? I would have thought some paths would be read-only and
you wouldn't want to allocate, even in virtual mode.
> #define IOMMU_TABLE_USERSPACE_ENTRY(tbl, entry) \
> - ((tbl)->it_ops->useraddrptr((tbl), (entry)))
> + ((tbl)->it_ops->useraddrptr((tbl), (entry), true))
>
> /* Pure 2^n version of get_order */
> static inline __attribute_const__
> diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h
> index 5e02408..1fa5590 100644
> --- a/arch/powerpc/platforms/powernv/pci.h
> +++ b/arch/powerpc/platforms/powernv/pci.h
> @@ -267,8 +267,10 @@ extern int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
> unsigned long attrs);
> extern void pnv_tce_free(struct iommu_table *tbl, long index, long npages);
> extern int pnv_tce_xchg(struct iommu_table *tbl, long index,
> - unsigned long *hpa, enum dma_data_direction *direction);
> -extern __be64 *pnv_tce_useraddrptr(struct iommu_table *tbl, long index);
> + unsigned long *hpa, enum dma_data_direction *direction,
> + bool alloc);
> +extern __be64 *pnv_tce_useraddrptr(struct iommu_table *tbl, long index,
> + bool alloc);
> extern unsigned long pnv_tce_get(struct iommu_table *tbl, long index);
>
> extern long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
> diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
> index db0490c..05b4865 100644
> --- a/arch/powerpc/kvm/book3s_64_vio_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
> @@ -200,7 +200,7 @@ static long kvmppc_rm_tce_iommu_mapped_dec(struct kvm *kvm,
> {
> struct mm_iommu_table_group_mem_t *mem = NULL;
> const unsigned long pgsize = 1ULL << tbl->it_page_shift;
> - __be64 *pua = IOMMU_TABLE_USERSPACE_ENTRY(tbl, entry);
> + __be64 *pua = IOMMU_TABLE_USERSPACE_ENTRY_RM(tbl, entry);
>
> if (!pua)
> /* it_userspace allocation might be delayed */
> @@ -264,7 +264,7 @@ static long kvmppc_rm_tce_iommu_do_map(struct kvm *kvm, struct iommu_table *tbl,
> {
> long ret;
> unsigned long hpa = 0;
> - __be64 *pua = IOMMU_TABLE_USERSPACE_ENTRY(tbl, entry);
> + __be64 *pua = IOMMU_TABLE_USERSPACE_ENTRY_RM(tbl, entry);
> struct mm_iommu_table_group_mem_t *mem;
>
> if (!pua)
> diff --git a/arch/powerpc/platforms/powernv/pci-ioda-tce.c b/arch/powerpc/platforms/powernv/pci-ioda-tce.c
> index 36c2eb0..a7debfb 100644
> --- a/arch/powerpc/platforms/powernv/pci-ioda-tce.c
> +++ b/arch/powerpc/platforms/powernv/pci-ioda-tce.c
> @@ -48,7 +48,7 @@ static __be64 *pnv_alloc_tce_level(int nid, unsigned int shift)
> return addr;
> }
>
> -static __be64 *pnv_tce(struct iommu_table *tbl, bool user, long idx)
> +static __be64 *pnv_tce(struct iommu_table *tbl, bool user, long idx, bool alloc)
> {
> __be64 *tmp = user ? tbl->it_userspace : (__be64 *) tbl->it_base;
> int level = tbl->it_indirect_levels;
> @@ -57,7 +57,20 @@ static __be64 *pnv_tce(struct iommu_table *tbl, bool user, long idx)
>
> while (level) {
> int n = (idx & mask) >> (level * shift);
> - unsigned long tce = be64_to_cpu(tmp[n]);
> + unsigned long tce;
> +
> + if (tmp[n] == 0) {
> + __be64 *tmp2;
> +
> + if (!alloc)
> + return NULL;
> +
> + tmp2 = pnv_alloc_tce_level(tbl->it_nid,
> + ilog2(tbl->it_level_size) + 3);
What if the allocation fails?
> + tmp[n] = cpu_to_be64(__pa(tmp2) |
> + TCE_PCI_READ | TCE_PCI_WRITE);
> + }
> + tce = be64_to_cpu(tmp[n]);
>
> tmp = __va(tce & ~(TCE_PCI_READ | TCE_PCI_WRITE));
> idx &= ~mask;
> @@ -84,7 +97,7 @@ int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
> ((rpn + i) << tbl->it_page_shift);
> unsigned long idx = index - tbl->it_offset + i;
>
> - *(pnv_tce(tbl, false, idx)) = cpu_to_be64(newtce);
> + *(pnv_tce(tbl, false, idx, true)) = cpu_to_be64(newtce);
> }
>
> return 0;
> @@ -92,31 +105,45 @@ int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
>
> #ifdef CONFIG_IOMMU_API
> int pnv_tce_xchg(struct iommu_table *tbl, long index,
> - unsigned long *hpa, enum dma_data_direction *direction)
> + unsigned long *hpa, enum dma_data_direction *direction,
> + bool alloc)
> {
> u64 proto_tce = iommu_direction_to_tce_perm(*direction);
> unsigned long newtce = *hpa | proto_tce, oldtce;
> unsigned long idx = index - tbl->it_offset;
> + __be64 *ptce;
>
> BUG_ON(*hpa & ~IOMMU_PAGE_MASK(tbl));
>
> if (newtce & TCE_PCI_WRITE)
> newtce |= TCE_PCI_READ;
>
> - oldtce = be64_to_cpu(xchg(pnv_tce(tbl, false, idx),
> - cpu_to_be64(newtce)));
> + ptce = pnv_tce(tbl, false, idx, alloc);
> + if (!ptce) {
> + if (*direction == DMA_NONE) {
> + *hpa = 0;
> + return 0;
> + }
> + /* It is likely to be realmode */
> + if (!alloc)
> + return H_TOO_HARD;
> +
> + return H_HARDWARE;
> + }
> +
> + oldtce = be64_to_cpu(xchg(ptce, cpu_to_be64(newtce)));
> *hpa = oldtce & ~(TCE_PCI_READ | TCE_PCI_WRITE);
> *direction = iommu_tce_direction(oldtce);
>
> return 0;
> }
>
> -__be64 *pnv_tce_useraddrptr(struct iommu_table *tbl, long index)
> +__be64 *pnv_tce_useraddrptr(struct iommu_table *tbl, long index, bool alloc)
> {
> if (WARN_ON_ONCE(!tbl->it_userspace))
> return NULL;
>
> - return pnv_tce(tbl, true, index - tbl->it_offset);
> + return pnv_tce(tbl, true, index - tbl->it_offset, alloc);
> }
> #endif
>
> @@ -126,14 +153,19 @@ void pnv_tce_free(struct iommu_table *tbl, long index, long npages)
>
> for (i = 0; i < npages; i++) {
> unsigned long idx = index - tbl->it_offset + i;
> + __be64 *ptce = pnv_tce(tbl, false, idx, false);
>
> - *(pnv_tce(tbl, false, idx)) = cpu_to_be64(0);
> + if (ptce)
> + *ptce = cpu_to_be64(0);
> }
> }
>
> unsigned long pnv_tce_get(struct iommu_table *tbl, long index)
> {
> - __be64 *ptce = pnv_tce(tbl, false, index - tbl->it_offset);
> + __be64 *ptce = pnv_tce(tbl, false, index - tbl->it_offset, false);
> +
> + if (!ptce)
> + return 0;
>
> return be64_to_cpu(*ptce);
> }
> @@ -224,6 +256,7 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
> unsigned int table_shift = max_t(unsigned int, entries_shift + 3,
> PAGE_SHIFT);
> const unsigned long tce_table_size = 1UL << table_shift;
> + unsigned int tmplevels = levels;
>
> if (!levels || (levels > POWERNV_IOMMU_MAX_LEVELS))
> return -EINVAL;
> @@ -231,6 +264,9 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
> if (!is_power_of_2(window_size))
> return -EINVAL;
>
> + if (alloc_userspace_copy && (window_size > (1ULL << 32)))
> + tmplevels = 1;
> +
> /* Adjust direct table size from window_size and levels */
> entries_shift = (entries_shift + levels - 1) / levels;
> level_shift = entries_shift + 3;
> @@ -241,7 +277,7 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
>
> /* Allocate TCE table */
> addr = pnv_pci_ioda2_table_do_alloc_pages(nid, level_shift,
> - levels, tce_table_size, &offset, &total_allocated);
> + tmplevels, tce_table_size, &offset, &total_allocated);
>
> /* addr==NULL means that the first level allocation failed */
> if (!addr)
> @@ -252,7 +288,7 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
> * we did not allocate as much as we wanted,
> * release partially allocated table.
> */
> - if (offset < tce_table_size)
> + if (tmplevels == levels && offset < tce_table_size)
> goto free_tces_exit;
>
> /* Allocate userspace view of the TCE table */
> @@ -263,8 +299,8 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
> &total_allocated_uas);
> if (!uas)
> goto free_tces_exit;
> - if (offset < tce_table_size ||
> - total_allocated_uas != total_allocated)
> + if (tmplevels == levels && (offset < tce_table_size ||
> + total_allocated_uas != total_allocated))
> goto free_uas_exit;
> }
>
> @@ -275,10 +311,11 @@ long pnv_pci_ioda2_table_alloc_pages(int nid, __u64 bus_offset,
> tbl->it_indirect_levels = levels - 1;
> tbl->it_allocated_size = total_allocated;
> tbl->it_userspace = uas;
> + tbl->it_nid = nid;
>
> - pr_debug("Created TCE table: ws=%08llx ts=%lx @%08llx base=%lx uas=%p levels=%d\n",
> + pr_debug("Created TCE table: ws=%08llx ts=%lx @%08llx base=%lx uas=%p levels=%d/%d\n",
> window_size, tce_table_size, bus_offset, tbl->it_base,
> - tbl->it_userspace, levels);
> + tbl->it_userspace, tmplevels, levels);
>
> return 0;
>
> diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
> index c61c04d..d9df620 100644
> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
> @@ -2010,7 +2010,7 @@ static int pnv_ioda1_tce_build(struct iommu_table *tbl, long index,
> static int pnv_ioda1_tce_xchg(struct iommu_table *tbl, long index,
> unsigned long *hpa, enum dma_data_direction *direction)
> {
> - long ret = pnv_tce_xchg(tbl, index, hpa, direction);
> + long ret = pnv_tce_xchg(tbl, index, hpa, direction, true);
>
> if (!ret)
> pnv_pci_p7ioc_tce_invalidate(tbl, index, 1, false);
> @@ -2021,7 +2021,7 @@ static int pnv_ioda1_tce_xchg(struct iommu_table *tbl, long index,
> static int pnv_ioda1_tce_xchg_rm(struct iommu_table *tbl, long index,
> unsigned long *hpa, enum dma_data_direction *direction)
> {
> - long ret = pnv_tce_xchg(tbl, index, hpa, direction);
> + long ret = pnv_tce_xchg(tbl, index, hpa, direction, false);
>
> if (!ret)
> pnv_pci_p7ioc_tce_invalidate(tbl, index, 1, true);
> @@ -2175,7 +2175,7 @@ static int pnv_ioda2_tce_build(struct iommu_table *tbl, long index,
> static int pnv_ioda2_tce_xchg(struct iommu_table *tbl, long index,
> unsigned long *hpa, enum dma_data_direction *direction)
> {
> - long ret = pnv_tce_xchg(tbl, index, hpa, direction);
> + long ret = pnv_tce_xchg(tbl, index, hpa, direction, true);
>
> if (!ret)
> pnv_pci_ioda2_tce_invalidate(tbl, index, 1, false);
> @@ -2186,7 +2186,7 @@ static int pnv_ioda2_tce_xchg(struct iommu_table *tbl, long index,
> static int pnv_ioda2_tce_xchg_rm(struct iommu_table *tbl, long index,
> unsigned long *hpa, enum dma_data_direction *direction)
> {
> - long ret = pnv_tce_xchg(tbl, index, hpa, direction);
> + long ret = pnv_tce_xchg(tbl, index, hpa, direction, false);
>
> if (!ret)
> pnv_pci_ioda2_tce_invalidate(tbl, index, 1, true);
> diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
> index 628a948..f040ab1 100644
> --- a/drivers/vfio/vfio_iommu_spapr_tce.c
> +++ b/drivers/vfio/vfio_iommu_spapr_tce.c
> @@ -639,7 +639,7 @@ static long tce_iommu_create_table(struct tce_container *container,
> page_shift, window_size, levels, ptbl);
>
> WARN_ON(!ret && !(*ptbl)->it_ops->free);
> - WARN_ON(!ret && ((*ptbl)->it_allocated_size != table_size));
> + WARN_ON(!ret && ((*ptbl)->it_allocated_size > table_size));
>
> return ret;
> }
--
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
* [PATCH] pci/shpchp: no claim on pcie port device
From: Pingfan Liu @ 2018-06-12 6:42 UTC (permalink / raw)
To: linux-pci; +Cc: Bjorn Helgaas, linuxppc-dev
The Linux Device Driver Model allows a physical device to be handled
by only a single driver. But at present, both shpchp and portdrv_pci
claim PCI_CLASS_BRIDGE_PCI, and touch devices_kset. This causes a
few problems, one is the wrong shutdown seq of devices, owing to the
broken devices_kset.
I hit this bug on a Power9 machine, when "kexec -e", and see a ata-disk
behind a bridge can not write back buffer in flight due to the former
shutdown of the bridge which clears the BusMaster bit.
Note the device involved:
0004:00:00.0 PCI bridge: IBM Device 04c1 (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
NUMA node: 0
Bus: primary=00, secondary=01, subordinate=12, sec-latency=0
I/O behind bridge: 00000000-00000fff
Memory behind bridge: 80000000-ffefffff
Prefetchable memory behind bridge: 0006024000000000-0006027f7fffffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
BridgeCtl: Parity- SERR+ NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [48] Express (v2) Root Port (Slot-), MSI 00
DevCap: MaxPayload 512 bytes, PhantFunc 0
ExtTag- RBE+
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 256 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
LnkCap: Port #0, Speed 8GT/s, Width x8, ASPM not supported, Exit Latency L0s <64ns, L1 <1us
ClockPM- Surprise- LLActRep+ BwNot+ ASPMOptComp-
LnkCtl: ASPM Disabled; RCB 128 bytes Disabled- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 8GT/s, Width x4, TrErr- Train- SlotClk- DLActive+ BWMgmt- ABWMgmt+
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible-
RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
DevCap2: Completion Timeout: Range ABCD, TimeoutDis+, LTR-, OBFF Not Supported ARIFwd+
DevCtl2: Completion Timeout: 16ms to 55ms, TimeoutDis+, LTR-, OBFF Disabled ARIFwd+
LnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-
Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
Compliance De-emphasis: -6dB
LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete+, EqualizationPhase1+
EqualizationPhase2+, EqualizationPhase3+, LinkEqualizationRequest-
Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UEMsk: DLP- SDES- TLP+ FCP- CmpltTO+ CmpltAbrt+ UnxCmplt- RxOF- MalfTLP- ECRC+ UnsupReq- ACSViol-
UESvrt: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
AERCap: First Error Pointer: 00, GenCap+ CGenEn+ ChkCap+ ChkEn+
Capabilities: [148 v1] #19
Signed-off-by: Pingfan Liu <kernelfans@gmail.com>
---
drivers/pci/hotplug/shpchp_core.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 1f0f969..2cd8e19 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -287,6 +287,13 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int rc;
struct controller *ctrl;
+ /* do not claim pcie port device */
+ if (pci_is_pcie(dev) &&
+ ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) ||
+ (pci_pcie_type(dev) == PCI_EXP_TYPE_UPSTREAM) ||
+ (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM)))
+ return -ENODEV;
+
if (!is_shpc_capable(pdev))
return -ENODEV;
--
2.7.4
^ permalink raw reply related
* Re: [PATCH v2 08/12] macintosh/via-pmu68k: Don't load driver on unsupported hardware
From: Laurent Vivier @ 2018-06-12 6:53 UTC (permalink / raw)
To: Finn Thain, Benjamin Herrenschmidt
Cc: Michael Schmitz, Andreas Schwab, linuxppc-dev, linux-m68k,
linux-kernel, Geert Uytterhoeven
In-Reply-To: <alpine.LNX.2.21.1806120911370.34@nippy.intranet>
On 12/06/2018 01:47, Finn Thain wrote:
> On Sun, 10 Jun 2018, Benjamin Herrenschmidt wrote:
...
> I don't know what the bootloader situation is, but it looks messy...
> http://nubus-pmac.sourceforge.net/#booters
>
> Laurent, does Emile work on these machines?
>
No, Emile doesn't work on pmac-nubus, I tried to implement the switch
from m68k to ppc, but it has never worked.
Laurent
^ permalink raw reply
* Re: [PATCH] pci/shpchp: no claim on pcie port device
From: kbuild test robot @ 2018-06-12 6:57 UTC (permalink / raw)
To: Pingfan Liu; +Cc: kbuild-all, linux-pci, Bjorn Helgaas, linuxppc-dev
In-Reply-To: <1528785733-19442-1-git-send-email-kernelfans@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2656 bytes --]
Hi Pingfan,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on v4.17]
[cannot apply to pci/next next-20180612]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Pingfan-Liu/pci-shpchp-no-claim-on-pcie-port-device/20180612-144419
config: i386-randconfig-x009-201823 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
drivers/pci/hotplug/shpchp_core.c: In function 'shpc_probe':
>> drivers/pci/hotplug/shpchp_core.c:291:18: error: 'dev' undeclared (first use in this function); did you mean 'pdev'?
if (pci_is_pcie(dev) &&
^~~
pdev
drivers/pci/hotplug/shpchp_core.c:291:18: note: each undeclared identifier is reported only once for each function it appears in
vim +291 drivers/pci/hotplug/shpchp_core.c
284
285 static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
286 {
287 int rc;
288 struct controller *ctrl;
289
290 /* do not claim pcie port device */
> 291 if (pci_is_pcie(dev) &&
292 ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) ||
293 (pci_pcie_type(dev) == PCI_EXP_TYPE_UPSTREAM) ||
294 (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM)))
295 return -ENODEV;
296
297 if (!is_shpc_capable(pdev))
298 return -ENODEV;
299
300 ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
301 if (!ctrl)
302 goto err_out_none;
303
304 INIT_LIST_HEAD(&ctrl->slot_list);
305
306 rc = shpc_init(ctrl, pdev);
307 if (rc) {
308 ctrl_dbg(ctrl, "Controller initialization failed\n");
309 goto err_out_free_ctrl;
310 }
311
312 pci_set_drvdata(pdev, ctrl);
313
314 /* Setup the slot information structures */
315 rc = init_slots(ctrl);
316 if (rc) {
317 ctrl_err(ctrl, "Slot initialization failed\n");
318 goto err_out_release_ctlr;
319 }
320
321 rc = shpchp_create_ctrl_files(ctrl);
322 if (rc)
323 goto err_cleanup_slots;
324
325 return 0;
326
327 err_cleanup_slots:
328 cleanup_slots(ctrl);
329 err_out_release_ctlr:
330 ctrl->hpc_ops->release_ctlr(ctrl);
331 err_out_free_ctrl:
332 kfree(ctrl);
333 err_out_none:
334 return -ENODEV;
335 }
336
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 32087 bytes --]
^ permalink raw reply
* Re: [PATCH] pci/shpchp: no claim on pcie port device
From: Pingfan Liu @ 2018-06-12 7:14 UTC (permalink / raw)
To: linux-pci; +Cc: Bjorn Helgaas, linuxppc-dev
In-Reply-To: <1528785733-19442-1-git-send-email-kernelfans@gmail.com>
On Tue, Jun 12, 2018 at 2:42 PM Pingfan Liu <kernelfans@gmail.com> wrote:
>
> The Linux Device Driver Model allows a physical device to be handled
> by only a single driver. But at present, both shpchp and portdrv_pci
> claim PCI_CLASS_BRIDGE_PCI, and touch devices_kset. This causes a
> few problems, one is the wrong shutdown seq of devices, owing to the
> broken devices_kset.
>
> I hit this bug on a Power9 machine, when "kexec -e", and see a ata-disk
> behind a bridge can not write back buffer in flight due to the former
> shutdown of the bridge which clears the BusMaster bit.
>
> Note the device involved:
> 0004:00:00.0 PCI bridge: IBM Device 04c1 (prog-if 00 [Normal decode])
> Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
> Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
> Latency: 0
> NUMA node: 0
> Bus: primary=00, secondary=01, subordinate=12, sec-latency=0
> I/O behind bridge: 00000000-00000fff
> Memory behind bridge: 80000000-ffefffff
> Prefetchable memory behind bridge: 0006024000000000-0006027f7fffffff
> Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
> BridgeCtl: Parity- SERR+ NoISA- VGA- MAbort- >Reset- FastB2B-
> PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
> Capabilities: [40] Power Management version 3
> Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
> Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
> Capabilities: [48] Express (v2) Root Port (Slot-), MSI 00
> DevCap: MaxPayload 512 bytes, PhantFunc 0
> ExtTag- RBE+
> DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
> RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
> MaxPayload 256 bytes, MaxReadReq 128 bytes
> DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
> LnkCap: Port #0, Speed 8GT/s, Width x8, ASPM not supported, Exit Latency L0s <64ns, L1 <1us
> ClockPM- Surprise- LLActRep+ BwNot+ ASPMOptComp-
> LnkCtl: ASPM Disabled; RCB 128 bytes Disabled- CommClk-
> ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
> LnkSta: Speed 8GT/s, Width x4, TrErr- Train- SlotClk- DLActive+ BWMgmt- ABWMgmt+
> RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible-
> RootCap: CRSVisible-
> RootSta: PME ReqID 0000, PMEStatus- PMEPending-
> DevCap2: Completion Timeout: Range ABCD, TimeoutDis+, LTR-, OBFF Not Supported ARIFwd+
> DevCtl2: Completion Timeout: 16ms to 55ms, TimeoutDis+, LTR-, OBFF Disabled ARIFwd+
> LnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-
> Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
> Compliance De-emphasis: -6dB
> LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete+, EqualizationPhase1+
> EqualizationPhase2+, EqualizationPhase3+, LinkEqualizationRequest-
> Capabilities: [100 v1] Advanced Error Reporting
> UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
> UEMsk: DLP- SDES- TLP+ FCP- CmpltTO+ CmpltAbrt+ UnxCmplt- RxOF- MalfTLP- ECRC+ UnsupReq- ACSViol-
> UESvrt: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
> CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
> CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
> AERCap: First Error Pointer: 00, GenCap+ CGenEn+ ChkCap+ ChkEn+
> Capabilities: [148 v1] #19
>
> Signed-off-by: Pingfan Liu <kernelfans@gmail.com>
> ---
> drivers/pci/hotplug/shpchp_core.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
> index 1f0f969..2cd8e19 100644
> --- a/drivers/pci/hotplug/shpchp_core.c
> +++ b/drivers/pci/hotplug/shpchp_core.c
> @@ -287,6 +287,13 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> int rc;
> struct controller *ctrl;
>
> + /* do not claim pcie port device */
> + if (pci_is_pcie(dev) &&
> + ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) ||
> + (pci_pcie_type(dev) == PCI_EXP_TYPE_UPSTREAM) ||
> + (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM)))
> + return -ENODEV;
> +
Sorry, should s/dev/pdev/. I will try to loan a power9 to test it.
NACK it, I will send out v2.
Thanks,
Pingfan
> if (!is_shpc_capable(pdev))
> return -ENODEV;
>
> --
> 2.7.4
>
^ permalink raw reply
* [RFC PATCH 0/3] couple of TLB flush optimisations
From: Nicholas Piggin @ 2018-06-12 7:16 UTC (permalink / raw)
To: linux-mm
Cc: Nicholas Piggin, linuxppc-dev, linux-arch, Aneesh Kumar K . V,
Minchan Kim, Mel Gorman, Nadav Amit, Andrew Morton,
Linus Torvalds
I'm just looking around TLB flushing and noticed a few issues with
the core code. The first one seems pretty straightforward, unless I
missed something, but the TLB flush pattern after the revert seems
okay.
The second one might be a bit more interesting for other architectures
and the big comment in include/asm-generic/tlb.h and linked mail from
Linus gives some good context.
I suspect mmu notifiers should use this precise TLB range too, because
I don't see how they could care about the page table structure under
the mapping. Although I only use it in powerpc so far.
Comments?
Thanks,
Nick
Nicholas Piggin (3):
Revert "mm: always flush VMA ranges affected by zap_page_range"
mm: mmu_gather track of invalidated TLB ranges explicitly for more
precise flushing
powerpc/64s/radix: optimise TLB flush with precise TLB ranges in
mmu_gather
arch/powerpc/mm/tlb-radix.c | 7 +++++--
include/asm-generic/tlb.h | 27 +++++++++++++++++++++++++--
mm/memory.c | 18 ++++--------------
3 files changed, 34 insertions(+), 18 deletions(-)
--
2.17.0
^ permalink raw reply
* [RFC PATCH 1/3] Revert "mm: always flush VMA ranges affected by zap_page_range"
From: Nicholas Piggin @ 2018-06-12 7:16 UTC (permalink / raw)
To: linux-mm
Cc: Nicholas Piggin, linuxppc-dev, linux-arch, Aneesh Kumar K . V,
Minchan Kim, Mel Gorman, Nadav Amit, Andrew Morton,
Linus Torvalds
In-Reply-To: <20180612071621.26775-1-npiggin@gmail.com>
This reverts commit 4647706ebeee6e50f7b9f922b095f4ec94d581c3.
Patch 99baac21e4585 ("mm: fix MADV_[FREE|DONTNEED] TLB flush miss
problem") provides a superset of the TLB flush coverage of this
commit, and even includes in the changelog "this patch supersedes
'mm: Always flush VMA ranges affected by zap_page_range v2'".
Reverting this avoids double flushing the TLB range, and the less
efficient flush_tlb_range() call (the mmu_gather API is more precise
about what ranges it invalidates).
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
mm/memory.c | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/mm/memory.c b/mm/memory.c
index 7206a634270b..9d472e00fc2d 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1603,20 +1603,8 @@ void zap_page_range(struct vm_area_struct *vma, unsigned long start,
tlb_gather_mmu(&tlb, mm, start, end);
update_hiwater_rss(mm);
mmu_notifier_invalidate_range_start(mm, start, end);
- for ( ; vma && vma->vm_start < end; vma = vma->vm_next) {
+ for ( ; vma && vma->vm_start < end; vma = vma->vm_next)
unmap_single_vma(&tlb, vma, start, end, NULL);
-
- /*
- * zap_page_range does not specify whether mmap_sem should be
- * held for read or write. That allows parallel zap_page_range
- * operations to unmap a PTE and defer a flush meaning that
- * this call observes pte_none and fails to flush the TLB.
- * Rather than adding a complex API, ensure that no stale
- * TLB entries exist when this call returns.
- */
- flush_tlb_range(vma, start, end);
- }
-
mmu_notifier_invalidate_range_end(mm, start, end);
tlb_finish_mmu(&tlb, start, end);
}
--
2.17.0
^ permalink raw reply related
* [RFC PATCH 2/3] mm: mmu_gather track of invalidated TLB ranges explicitly for more precise flushing
From: Nicholas Piggin @ 2018-06-12 7:16 UTC (permalink / raw)
To: linux-mm
Cc: Nicholas Piggin, linuxppc-dev, linux-arch, Aneesh Kumar K . V,
Minchan Kim, Mel Gorman, Nadav Amit, Andrew Morton,
Linus Torvalds
In-Reply-To: <20180612071621.26775-1-npiggin@gmail.com>
The mmu_gather APIs keep track of the invalidated address range
including the span covered by invalidated page table pages. Page table
pages with no ptes (and therefore could not have TLB entries) still
need to be involved in the invalidation if the processor caches
intermediate levels of the page table.
This allows a backwards compatible / legacy implementation to cache
page tables without modification, if they invalidate their page table
cache using their existing tlb invalidation instructions.
However this additional flush range is not necessary if the
architecture provides explicit page table cache management, or if it
ensures that page table cache entries will never be instantiated if
they did not reach a valid pte.
This is very noticable on powerpc in the exec path, in shift_arg_pages
where the TLB flushing for the page table teardown is a very large
range that gets implemented as a full process flush. This patch
provides page_start and page_end fields to mmu_gather which
architectures can use to optimise their TLB flushing.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
include/asm-generic/tlb.h | 27 +++++++++++++++++++++++++--
mm/memory.c | 4 +++-
2 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index faddde44de8c..a006f702b4c2 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -96,6 +96,8 @@ struct mmu_gather {
#endif
unsigned long start;
unsigned long end;
+ unsigned long page_start;
+ unsigned long page_end;
/* we are in the middle of an operation to clear
* a full mm and can make some optimizations */
unsigned int fullmm : 1,
@@ -128,13 +130,25 @@ static inline void __tlb_adjust_range(struct mmu_gather *tlb,
tlb->end = max(tlb->end, address + range_size);
}
+static inline void __tlb_adjust_page_range(struct mmu_gather *tlb,
+ unsigned long address,
+ unsigned int range_size)
+{
+ tlb->page_start = min(tlb->page_start, address);
+ tlb->page_end = max(tlb->page_end, address + range_size);
+}
+
+
static inline void __tlb_reset_range(struct mmu_gather *tlb)
{
if (tlb->fullmm) {
tlb->start = tlb->end = ~0;
+ tlb->page_start = tlb->page_end = ~0;
} else {
tlb->start = TASK_SIZE;
tlb->end = 0;
+ tlb->page_start = TASK_SIZE;
+ tlb->page_end = 0;
}
}
@@ -210,12 +224,14 @@ static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
#define tlb_remove_tlb_entry(tlb, ptep, address) \
do { \
__tlb_adjust_range(tlb, address, PAGE_SIZE); \
+ __tlb_adjust_page_range(tlb, address, PAGE_SIZE); \
__tlb_remove_tlb_entry(tlb, ptep, address); \
} while (0)
#define tlb_remove_huge_tlb_entry(h, tlb, ptep, address) \
do { \
__tlb_adjust_range(tlb, address, huge_page_size(h)); \
+ __tlb_adjust_page_range(tlb, address, huge_page_size(h)); \
__tlb_remove_tlb_entry(tlb, ptep, address); \
} while (0)
@@ -230,6 +246,7 @@ static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
#define tlb_remove_pmd_tlb_entry(tlb, pmdp, address) \
do { \
__tlb_adjust_range(tlb, address, HPAGE_PMD_SIZE); \
+ __tlb_adjust_page_range(tlb, address, HPAGE_PMD_SIZE); \
__tlb_remove_pmd_tlb_entry(tlb, pmdp, address); \
} while (0)
@@ -244,6 +261,7 @@ static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
#define tlb_remove_pud_tlb_entry(tlb, pudp, address) \
do { \
__tlb_adjust_range(tlb, address, HPAGE_PUD_SIZE); \
+ __tlb_adjust_page_range(tlb, address, HPAGE_PUD_SIZE); \
__tlb_remove_pud_tlb_entry(tlb, pudp, address); \
} while (0)
@@ -262,6 +280,11 @@ static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
* architecture to do its own odd thing, not cause pain for others
* http://lkml.kernel.org/r/CA+55aFzBggoXtNXQeng5d_mRoDnaMBE5Y+URs+PHR67nUpMtaw@mail.gmail.com
*
+ * Powerpc (Book3S 64-bit) with the radix MMU has an architected "page
+ * walk cache" that is invalidated with a specific instruction. It uses
+ * need_flush_all to issue this instruction, which is set by its own
+ * __p??_free_tlb functions.
+ *
* For now w.r.t page table cache, mark the range_size as PAGE_SIZE
*/
@@ -273,7 +296,7 @@ static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
#define pmd_free_tlb(tlb, pmdp, address) \
do { \
- __tlb_adjust_range(tlb, address, PAGE_SIZE); \
+ __tlb_adjust_range(tlb, address, PAGE_SIZE); \
__pmd_free_tlb(tlb, pmdp, address); \
} while (0)
@@ -288,7 +311,7 @@ static inline void tlb_remove_check_page_size_change(struct mmu_gather *tlb,
#ifndef __ARCH_HAS_5LEVEL_HACK
#define p4d_free_tlb(tlb, pudp, address) \
do { \
- __tlb_adjust_range(tlb, address, PAGE_SIZE); \
+ __tlb_adjust_range(tlb, address, PAGE_SIZE); \
__p4d_free_tlb(tlb, pudp, address); \
} while (0)
#endif
diff --git a/mm/memory.c b/mm/memory.c
index 9d472e00fc2d..a46896b85e54 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -277,8 +277,10 @@ void arch_tlb_finish_mmu(struct mmu_gather *tlb,
{
struct mmu_gather_batch *batch, *next;
- if (force)
+ if (force) {
__tlb_adjust_range(tlb, start, end - start);
+ __tlb_adjust_page_range(tlb, start, end - start);
+ }
tlb_flush_mmu(tlb);
--
2.17.0
^ permalink raw reply related
* [RFC PATCH 3/3] powerpc/64s/radix: optimise TLB flush with precise TLB ranges in mmu_gather
From: Nicholas Piggin @ 2018-06-12 7:16 UTC (permalink / raw)
To: linux-mm
Cc: Nicholas Piggin, linuxppc-dev, linux-arch, Aneesh Kumar K . V,
Minchan Kim, Mel Gorman, Nadav Amit, Andrew Morton,
Linus Torvalds
In-Reply-To: <20180612071621.26775-1-npiggin@gmail.com>
Use the page_start and page_end fields of mmu_gather to implement more
precise TLB flushing. (start, end) covers the entire TLB and page
table range that has been invalidated, for architectures that do not
have explicit page walk cache management. page_start and page_end are
just for ranges that may have TLB entries.
A tlb_flush may have no pages in this range, but still requires PWC
to be flushed. That is handled properly.
This brings the number of tlbiel instructions required by a kernel
compile from 33M to 25M, most avoided from exec->shift_arg_pages.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/mm/tlb-radix.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/mm/tlb-radix.c b/arch/powerpc/mm/tlb-radix.c
index 67a6e86d3e7e..06452ad701cf 100644
--- a/arch/powerpc/mm/tlb-radix.c
+++ b/arch/powerpc/mm/tlb-radix.c
@@ -853,8 +853,11 @@ void radix__tlb_flush(struct mmu_gather *tlb)
else
radix__flush_all_mm(mm);
} else {
- unsigned long start = tlb->start;
- unsigned long end = tlb->end;
+ unsigned long start = tlb->page_start;
+ unsigned long end = tlb->page_end;
+
+ if (end < start)
+ end = start;
if (!tlb->need_flush_all)
radix__flush_tlb_range_psize(mm, start, end, psize);
--
2.17.0
^ permalink raw reply related
* Re: [PATCH] pci/shpchp: no claim on pcie port device
From: Pingfan Liu @ 2018-06-12 7:20 UTC (permalink / raw)
To: hch; +Cc: linux-pci, Bjorn Helgaas, linuxppc-dev
In-Reply-To: <20180612065727.GA5195@infradead.org>
On Tue, Jun 12, 2018 at 2:57 PM Christoph Hellwig <hch@infradead.org> wrote:
>
> On Tue, Jun 12, 2018 at 02:42:13PM +0800, Pingfan Liu wrote:
> > The Linux Device Driver Model allows a physical device to be handled
> > by only a single driver. But at present, both shpchp and portdrv_pci
> > claim PCI_CLASS_BRIDGE_PCI, and touch devices_kset. This causes a
> > few problems, one is the wrong shutdown seq of devices, owing to the
> > broken devices_kset.
>
> How can they both touch devices_kset? Once one driver has claimed the
> device it should not be available to others.
>
Unfortunately, it could be. There are two code path for do_one_initcall
kernel_init->..->do_one_initcall->pcie_portdrv_init
And
load_module->do_init_module->do_one_initcall->shpcd_init
> > + /* do not claim pcie port device */
> > + if (pci_is_pcie(dev) &&
> > + ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) ||
> > + (pci_pcie_type(dev) == PCI_EXP_TYPE_UPSTREAM) ||
> > + (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM)))
> > + return -ENODEV;
>
> No need for the inner braces.
OK.
Thanks,
Pingfan
^ permalink raw reply
* Re: [PATCH] pci/shpchp: no claim on pcie port device
From: Christoph Hellwig @ 2018-06-12 6:57 UTC (permalink / raw)
To: Pingfan Liu; +Cc: linux-pci, Bjorn Helgaas, linuxppc-dev
In-Reply-To: <1528785733-19442-1-git-send-email-kernelfans@gmail.com>
On Tue, Jun 12, 2018 at 02:42:13PM +0800, Pingfan Liu wrote:
> The Linux Device Driver Model allows a physical device to be handled
> by only a single driver. But at present, both shpchp and portdrv_pci
> claim PCI_CLASS_BRIDGE_PCI, and touch devices_kset. This causes a
> few problems, one is the wrong shutdown seq of devices, owing to the
> broken devices_kset.
How can they both touch devices_kset? Once one driver has claimed the
device it should not be available to others.
> + /* do not claim pcie port device */
> + if (pci_is_pcie(dev) &&
> + ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) ||
> + (pci_pcie_type(dev) == PCI_EXP_TYPE_UPSTREAM) ||
> + (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM)))
> + return -ENODEV;
No need for the inner braces.
^ permalink raw reply
* Re: 4.17.0-10146-gf0dc7f9c6dd9: hw csum failure on powerpc+sungem
From: Balbir Singh @ 2018-06-12 7:37 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <CA+7wUsw_8znPDsej=j48kkmqV3vPbOuDociBE4tth53-Zj32qA@mail.gmail.com>
On 12/06/18 06:20, Mathieu Malaterre wrote:
> Hi Meelis,
>
> On Mon, Jun 11, 2018 at 1:21 PM Meelis Roos <mroos@linux.ee> wrote:
>> I am seeing this on PowerMac G4 with sungem ethernet driver. 4.17 was
>> OK, 4.17.0-10146-gf0dc7f9c6dd9 is problematic.
> Same here.
>
>> [ 140.518664] eth0: hw csum failure
>> [ 140.518699] CPU: 0 PID: 1237 Comm: postconf Not tainted 4.17.0-10146-gf0dc7f9c6dd9 #83
>> [ 140.518707] Call Trace:
>> [ 140.518734] [effefd90] [c03d6db8] __skb_checksum_complete+0xd8/0xdc (unreliable)
>> [ 140.518759] [effefdb0] [c04c1284] icmpv6_rcv+0x248/0x4ec
>> [ 140.518775] [effefdd0] [c049a448] ip6_input_finish.constprop.0+0x11c/0x5f4
>> [ 140.518786] [effefe10] [c049b1c0] ip6_mc_input+0xcc/0x100
>> [ 140.518807] [effefe20] [c03e110c] __netif_receive_skb_core+0x310/0x944
>> [ 140.518820] [effefe70] [c03e76ec] napi_gro_receive+0xd0/0xe8
>> [ 140.518845] [effefe80] [f3e1f66c] gem_poll+0x618/0x1274 [sungem]
>> [ 140.518856] [effeff30] [c03e6f0c] net_rx_action+0x198/0x374
>> [ 140.518872] [effeff90] [c0501a88] __do_softirq+0x120/0x278
>> [ 140.518890] [effeffe0] [c0036188] irq_exit+0xd8/0xdc
>> [ 140.518908] [effefff0] [c000f478] call_do_irq+0x24/0x3c
>> [ 140.518925] [d05a5d30] [c0007120] do_IRQ+0x74/0xf0
>> [ 140.518941] [d05a5d50] [c0012474] ret_from_except+0x0/0x14
>> [ 140.518960] --- interrupt: 501 at copy_page+0x40/0x90
>> LR = copy_user_page+0x18/0x30
>> [ 140.518973] [d05a5e10] [d058cd80] 0xd058cd80 (unreliable)
>> [ 140.518989] [d05a5e20] [c00fa2bc] wp_page_copy+0xec/0x654
>> [ 140.519002] [d05a5e60] [c00fd3a4] do_wp_page+0xa8/0x5b4
>> [ 140.519013] [d05a5e90] [c00fe934] handle_mm_fault+0x564/0xa84
>> [ 140.519025] [d05a5f00] [c0016230] do_page_fault+0x1bc/0x7e8
>> [ 140.519037] [d05a5f40] [c0012300] handle_page_fault+0x14/0x40
>> [ 140.519048] --- interrupt: 301 at 0xb78b6864
>> LR = 0xb78b6c54
>>
> For some reason if I do a git bisect it returns that:
>
> $ git bisect good
> 3036bc45364f98515a2c446d7fac2c34dcfbeff4 is the first bad commit
>
> Could you also check on your side please.
Don't have a G4, but the related commits look like
373e098e1e788d7b89ec0f31765a6c08e2ea0f7c and e9c4943a107b56696e4872cdffdba6b0c7277c77 Balbir
^ permalink raw reply
* Re: [PATCH] pci/shpchp: no claim on pcie port device
From: kbuild test robot @ 2018-06-12 7:37 UTC (permalink / raw)
To: Pingfan Liu; +Cc: kbuild-all, linux-pci, Bjorn Helgaas, linuxppc-dev
In-Reply-To: <1528785733-19442-1-git-send-email-kernelfans@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2611 bytes --]
Hi Pingfan,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on v4.17]
[cannot apply to pci/next next-20180612]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Pingfan-Liu/pci-shpchp-no-claim-on-pcie-port-device/20180612-144419
config: i386-randconfig-a1-201823 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All errors (new ones prefixed by >>):
drivers/pci/hotplug/shpchp_core.c: In function 'shpc_probe':
>> drivers/pci/hotplug/shpchp_core.c:291:18: error: 'dev' undeclared (first use in this function)
if (pci_is_pcie(dev) &&
^
drivers/pci/hotplug/shpchp_core.c:291:18: note: each undeclared identifier is reported only once for each function it appears in
vim +/dev +291 drivers/pci/hotplug/shpchp_core.c
284
285 static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
286 {
287 int rc;
288 struct controller *ctrl;
289
290 /* do not claim pcie port device */
> 291 if (pci_is_pcie(dev) &&
292 ((pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) ||
293 (pci_pcie_type(dev) == PCI_EXP_TYPE_UPSTREAM) ||
294 (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM)))
295 return -ENODEV;
296
297 if (!is_shpc_capable(pdev))
298 return -ENODEV;
299
300 ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
301 if (!ctrl)
302 goto err_out_none;
303
304 INIT_LIST_HEAD(&ctrl->slot_list);
305
306 rc = shpc_init(ctrl, pdev);
307 if (rc) {
308 ctrl_dbg(ctrl, "Controller initialization failed\n");
309 goto err_out_free_ctrl;
310 }
311
312 pci_set_drvdata(pdev, ctrl);
313
314 /* Setup the slot information structures */
315 rc = init_slots(ctrl);
316 if (rc) {
317 ctrl_err(ctrl, "Slot initialization failed\n");
318 goto err_out_release_ctlr;
319 }
320
321 rc = shpchp_create_ctrl_files(ctrl);
322 if (rc)
323 goto err_cleanup_slots;
324
325 return 0;
326
327 err_cleanup_slots:
328 cleanup_slots(ctrl);
329 err_out_release_ctlr:
330 ctrl->hpc_ops->release_ctlr(ctrl);
331 err_out_free_ctrl:
332 kfree(ctrl);
333 err_out_none:
334 return -ENODEV;
335 }
336
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28049 bytes --]
^ permalink raw reply
* Re: 4.17.0-10146-gf0dc7f9c6dd9: hw csum failure on powerpc+sungem
From: Mathieu Malaterre @ 2018-06-12 8:15 UTC (permalink / raw)
To: Balbir Singh, Christophe LEROY; +Cc: linuxppc-dev
In-Reply-To: <4030b744-f99c-bdfc-5f95-c9311e31ad0c@gmail.com>
Hi Balbir,
On Tue, Jun 12, 2018 at 9:39 AM Balbir Singh <bsingharora@gmail.com> wrote:
>
>
> On 12/06/18 06:20, Mathieu Malaterre wrote:
>
> > Hi Meelis,
> >
> > On Mon, Jun 11, 2018 at 1:21 PM Meelis Roos <mroos@linux.ee> wrote:
> >> I am seeing this on PowerMac G4 with sungem ethernet driver. 4.17 was
> >> OK, 4.17.0-10146-gf0dc7f9c6dd9 is problematic.
> > Same here.
> >
> >> [ 140.518664] eth0: hw csum failure
> >> [ 140.518699] CPU: 0 PID: 1237 Comm: postconf Not tainted 4.17.0-10146-gf0dc7f9c6dd9 #83
> >> [ 140.518707] Call Trace:
> >> [ 140.518734] [effefd90] [c03d6db8] __skb_checksum_complete+0xd8/0xdc (unreliable)
> >> [ 140.518759] [effefdb0] [c04c1284] icmpv6_rcv+0x248/0x4ec
> >> [ 140.518775] [effefdd0] [c049a448] ip6_input_finish.constprop.0+0x11c/0x5f4
> >> [ 140.518786] [effefe10] [c049b1c0] ip6_mc_input+0xcc/0x100
> >> [ 140.518807] [effefe20] [c03e110c] __netif_receive_skb_core+0x310/0x944
> >> [ 140.518820] [effefe70] [c03e76ec] napi_gro_receive+0xd0/0xe8
> >> [ 140.518845] [effefe80] [f3e1f66c] gem_poll+0x618/0x1274 [sungem]
> >> [ 140.518856] [effeff30] [c03e6f0c] net_rx_action+0x198/0x374
> >> [ 140.518872] [effeff90] [c0501a88] __do_softirq+0x120/0x278
> >> [ 140.518890] [effeffe0] [c0036188] irq_exit+0xd8/0xdc
> >> [ 140.518908] [effefff0] [c000f478] call_do_irq+0x24/0x3c
> >> [ 140.518925] [d05a5d30] [c0007120] do_IRQ+0x74/0xf0
> >> [ 140.518941] [d05a5d50] [c0012474] ret_from_except+0x0/0x14
> >> [ 140.518960] --- interrupt: 501 at copy_page+0x40/0x90
> >> LR = copy_user_page+0x18/0x30
> >> [ 140.518973] [d05a5e10] [d058cd80] 0xd058cd80 (unreliable)
> >> [ 140.518989] [d05a5e20] [c00fa2bc] wp_page_copy+0xec/0x654
> >> [ 140.519002] [d05a5e60] [c00fd3a4] do_wp_page+0xa8/0x5b4
> >> [ 140.519013] [d05a5e90] [c00fe934] handle_mm_fault+0x564/0xa84
> >> [ 140.519025] [d05a5f00] [c0016230] do_page_fault+0x1bc/0x7e8
> >> [ 140.519037] [d05a5f40] [c0012300] handle_page_fault+0x14/0x40
> >> [ 140.519048] --- interrupt: 301 at 0xb78b6864
> >> LR = 0xb78b6c54
> >>
> > For some reason if I do a git bisect it returns that:
> >
> > $ git bisect good
> > 3036bc45364f98515a2c446d7fac2c34dcfbeff4 is the first bad commit
> >
> > Could you also check on your side please.
>
> Don't have a G4, but the related commits look like
>
> 373e098e1e788d7b89ec0f31765a6c08e2ea0f7c and e9c4943a107b56696e4872cdffdba6b0c7277c77 Balbir
>
Indeed that makes more sense. I must have messed up during my
git-bisect operation. Will try a simple git-revert on those and report
back.
Thanks
^ permalink raw reply
* Re: [PATCH v5 1/4] resource: Move reparent_resources() to kernel/resource.c and make it public
From: Andy Shevchenko @ 2018-06-12 8:29 UTC (permalink / raw)
To: Baoquan He
Cc: Linux Kernel Mailing List, Andrew Morton, Rob Herring,
Dan Williams, Nicolas Pitre, Josh Triplett, kbuild test robot,
Borislav Petkov, Patrik Jakobsson, David Airlie, KY Srinivasan,
Haiyang Zhang, Stephen Hemminger, Dmitry Torokhov, Frank Rowand,
Keith Busch, Jon Derrick, Lorenzo Pieralisi, Bjorn Helgaas,
Thomas Gleixner, brijesh.singh, Jérôme Glisse,
Tom Lendacky, Greg Kroah-Hartman, baiyaowei, richard.weiyang,
devel, linux-input, linux-nvdimm, devicetree, linux-pci,
Eric Biederman, Vivek Goyal, Dave Young, Yinghai Lu, kexec,
Michal Simek, David S. Miller, Chris Zankel, Max Filippov,
Gustavo Padovan, Maarten Lankhorst, Sean Paul, linux-parisc,
open list:LINUX FOR POWERPC PA SEMI PWRFICIENT,
Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
In-Reply-To: <20180612032831.29747-2-bhe@redhat.com>
On Tue, Jun 12, 2018 at 6:28 AM, Baoquan He <bhe@redhat.com> wrote:
> reparent_resources() is duplicated in arch/microblaze/pci/pci-common.c
> and arch/powerpc/kernel/pci-common.c, so move it to kernel/resource.c
> so that it's shared. Later its code also need be updated using list_head
> to replace singly linked list.
While this is a good deduplication of the code, some requirements for
public functions would be good to satisfy.
> +/*
> + * Reparent resource children of pr that conflict with res
> + * under res, and make res replace those children.
> + */
kernel doc format, though...
> +static int reparent_resources(struct resource *parent,
> + struct resource *res)
...is it really public with static keyword?!
> +{
> + for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
> + if (p->end < res->start)
> + continue;
> + if (res->end < p->start)
> + break;
> + if (p->start < res->start || p->end > res->end)
> + return -1; /* not completely contained */
Usually we are expecting real eeror codes.
> + if (firstpp == NULL)
> + firstpp = pp;
> + }
> + if (firstpp == NULL)
> + return -1; /* didn't find any conflicting entries? */
Ditto.
> +}
> +EXPORT_SYMBOL(reparent_resources);
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* [PATCH v6 1/4] selftests/powerpc: add test for 32 bits memcmp
From: Christophe Leroy @ 2018-06-12 9:14 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
wei.guo.simon, segher
Cc: linux-kernel, linuxppc-dev
This patch renames memcmp test to memcmp_64 and adds
a memcmp_32 test for testing the 32 bits version of memcmp()
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
v6: no change
v5: no change
v4: new
tools/testing/selftests/powerpc/stringloops/Makefile | 14 +++++++++++---
tools/testing/selftests/powerpc/stringloops/memcmp_32.S | 1 +
2 files changed, 12 insertions(+), 3 deletions(-)
create mode 120000 tools/testing/selftests/powerpc/stringloops/memcmp_32.S
diff --git a/tools/testing/selftests/powerpc/stringloops/Makefile b/tools/testing/selftests/powerpc/stringloops/Makefile
index 1125e489055e..1e7301d4bac9 100644
--- a/tools/testing/selftests/powerpc/stringloops/Makefile
+++ b/tools/testing/selftests/powerpc/stringloops/Makefile
@@ -1,10 +1,18 @@
# SPDX-License-Identifier: GPL-2.0
# The loops are all 64-bit code
-CFLAGS += -m64
CFLAGS += -I$(CURDIR)
-TEST_GEN_PROGS := memcmp
-EXTRA_SOURCES := memcmp_64.S ../harness.c
+EXTRA_SOURCES := ../harness.c
+
+$(OUTPUT)/memcmp_64: memcmp.c
+$(OUTPUT)/memcmp_64: CFLAGS += -m64
+
+$(OUTPUT)/memcmp_32: memcmp.c
+$(OUTPUT)/memcmp_32: CFLAGS += -m32
+
+ASFLAGS = $(CFLAGS)
+
+TEST_GEN_PROGS := memcmp_32 memcmp_64
include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/stringloops/memcmp_32.S b/tools/testing/selftests/powerpc/stringloops/memcmp_32.S
new file mode 120000
index 000000000000..056f2b3af789
--- /dev/null
+++ b/tools/testing/selftests/powerpc/stringloops/memcmp_32.S
@@ -0,0 +1 @@
+../../../../../arch/powerpc/lib/memcmp_32.S
\ No newline at end of file
--
2.13.3
^ permalink raw reply related
* [PATCH v6 2/4] selftests/powerpc: Add test for strlen()
From: Christophe Leroy @ 2018-06-12 9:14 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
wei.guo.simon, segher
Cc: linux-kernel, linuxppc-dev
In-Reply-To: <85de16f5629ac9f4a815230cced361908758b53a.1528791416.git.christophe.leroy@c-s.fr>
This patch adds a test for strlen()
string.c contains a copy of strlen() from lib/string.c
The test first tests the correctness of strlen() by comparing
the result with libc strlen(). It tests all cases of alignment.
It them tests the duration of an aligned strlen() on a 4 bytes string,
on a 16 bytes string and on a 256 bytes string.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
v6: refactorised the benchmark test
v5: no change
v4: new
.../testing/selftests/powerpc/stringloops/Makefile | 5 +-
.../testing/selftests/powerpc/stringloops/string.c | 36 ++++++
.../testing/selftests/powerpc/stringloops/strlen.c | 127 +++++++++++++++++++++
3 files changed, 167 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/stringloops/string.c
create mode 100644 tools/testing/selftests/powerpc/stringloops/strlen.c
diff --git a/tools/testing/selftests/powerpc/stringloops/Makefile b/tools/testing/selftests/powerpc/stringloops/Makefile
index 1e7301d4bac9..df663ee9ddb3 100644
--- a/tools/testing/selftests/powerpc/stringloops/Makefile
+++ b/tools/testing/selftests/powerpc/stringloops/Makefile
@@ -10,9 +10,12 @@ $(OUTPUT)/memcmp_64: CFLAGS += -m64
$(OUTPUT)/memcmp_32: memcmp.c
$(OUTPUT)/memcmp_32: CFLAGS += -m32
+$(OUTPUT)/strlen: strlen.c string.o
+$(OUTPUT)/string.o: string.c
+
ASFLAGS = $(CFLAGS)
-TEST_GEN_PROGS := memcmp_32 memcmp_64
+TEST_GEN_PROGS := memcmp_32 memcmp_64 strlen
include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/stringloops/string.c b/tools/testing/selftests/powerpc/stringloops/string.c
new file mode 100644
index 000000000000..d05200481017
--- /dev/null
+++ b/tools/testing/selftests/powerpc/stringloops/string.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/lib/string.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+
+/*
+ * stupid library routines.. The optimized versions should generally be found
+ * as inline code in <asm-xx/string.h>
+ *
+ * These are buggy as well..
+ *
+ * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
+ * - Added strsep() which will replace strtok() soon (because strsep() is
+ * reentrant and should be faster). Use only strsep() in new code, please.
+ *
+ * * Sat Feb 09 2002, Jason Thomas <jason@topic.com.au>,
+ * Matthew Hawkins <matt@mh.dropbear.id.au>
+ * - Kissed strtok() goodbye
+ */
+
+#include <stddef.h>
+
+/**
+ * strlen - Find the length of a string
+ * @s: The string to be sized
+ */
+size_t test_strlen(const char *s)
+{
+ const char *sc;
+
+ for (sc = s; *sc != '\0'; ++sc)
+ /* nothing */;
+ return sc - s;
+}
diff --git a/tools/testing/selftests/powerpc/stringloops/strlen.c b/tools/testing/selftests/powerpc/stringloops/strlen.c
new file mode 100644
index 000000000000..9055ebc484d0
--- /dev/null
+++ b/tools/testing/selftests/powerpc/stringloops/strlen.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <malloc.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "utils.h"
+
+#define SIZE 256
+#define ITERATIONS 1000
+#define ITERATIONS_BENCH 100000
+
+int test_strlen(const void *s);
+
+/* test all offsets and lengths */
+static void test_one(char *s)
+{
+ unsigned long offset;
+
+ for (offset = 0; offset < SIZE; offset++) {
+ int x, y;
+ unsigned long i;
+
+ y = strlen(s + offset);
+ x = test_strlen(s + offset);
+
+ if (x != y) {
+ printf("strlen() returned %d, should have returned %d (%p offset %ld)\n", x, y, s, offset);
+
+ for (i = offset; i < SIZE; i++)
+ printf("%02x ", s[i]);
+ printf("\n");
+ }
+ }
+}
+
+static void bench_test(char *s)
+{
+ struct timespec ts_start, ts_end;
+ int i;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts_start);
+
+ for (i = 0; i < ITERATIONS_BENCH; i++)
+ test_strlen(s);
+
+ clock_gettime(CLOCK_MONOTONIC, &ts_end);
+
+ printf("len %3.3d : time = %.6f\n", test_strlen(s), ts_end.tv_sec - ts_start.tv_sec + (ts_end.tv_nsec - ts_start.tv_nsec) / 1e9);
+}
+
+static int testcase(void)
+{
+ char *s;
+ unsigned long i;
+
+ s = memalign(128, SIZE);
+ if (!s) {
+ perror("memalign");
+ exit(1);
+ }
+
+ srandom(1);
+
+ memset(s, 0, SIZE);
+ for (i = 0; i < SIZE; i++) {
+ char c;
+
+ do {
+ c = random() & 0x7f;
+ } while (!c);
+ s[i] = c;
+ test_one(s);
+ }
+
+ for (i = 0; i < ITERATIONS; i++) {
+ unsigned long j;
+
+ for (j = 0; j < SIZE; j++) {
+ char c;
+
+ do {
+ c = random() & 0x7f;
+ } while (!c);
+ s[j] = c;
+ }
+ for (j = 0; j < sizeof(long); j++) {
+ s[SIZE - 1 - j] = 0;
+ test_one(s);
+ }
+ }
+
+ for (i = 0; i < SIZE; i++) {
+ char c;
+
+ do {
+ c = random() & 0x7f;
+ } while (!c);
+ s[i] = c;
+ }
+
+ bench_test(s);
+
+ s[16] = 0;
+ bench_test(s);
+
+ s[8] = 0;
+ bench_test(s);
+
+ s[4] = 0;
+ bench_test(s);
+
+ s[3] = 0;
+ bench_test(s);
+
+ s[2] = 0;
+ bench_test(s);
+
+ s[1] = 0;
+ bench_test(s);
+
+ return 0;
+}
+
+int main(void)
+{
+ return test_harness(testcase, "strlen");
+}
--
2.13.3
^ permalink raw reply related
* [PATCH v6 3/4] powerpc/lib: implement strlen() in assembly
From: Christophe Leroy @ 2018-06-12 9:14 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
wei.guo.simon, segher
Cc: linux-kernel, linuxppc-dev
In-Reply-To: <85de16f5629ac9f4a815230cced361908758b53a.1528791416.git.christophe.leroy@c-s.fr>
The generic implementation of strlen() reads strings byte per byte.
This patch implements strlen() in assembly based on a read of entire
words, in the same spirit as what some other arches and glibc do.
On a 8xx the time spent in strlen is reduced by 3/4 for long strings.
strlen() selftest on an 8xx provides the following values:
Before the patch (ie with the generic strlen() in lib/string.c):
len 256 : time = 1.195055
len 016 : time = 0.083745
len 008 : time = 0.046828
len 004 : time = 0.028390
After the patch:
len 256 : time = 0.272185 ==> 78% improvment
len 016 : time = 0.040632 ==> 51% improvment
len 008 : time = 0.033060 ==> 29% improvment
len 004 : time = 0.029149 ==> 2% degradation
On a 832x:
Before the patch:
len 256 : time = 0.236125
len 016 : time = 0.018136
len 008 : time = 0.011000
len 004 : time = 0.007229
After the patch:
len 256 : time = 0.094950 ==> 60% improvment
len 016 : time = 0.013357 ==> 26% improvment
len 008 : time = 0.010586 ==> 4% improvment
len 004 : time = 0.008784
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
Not tested on PPC64.
Changes in v6:
- Reworked for having branchless conclusion
Changes in v5:
- Fixed for PPC64 LITTLE ENDIAN
Changes in v4:
- Added alignment of the loop
- doing the andc only if still not 0 as it happends only for bytes above 0x7f which is pretty rare in a string
Changes in v3:
- Made it common to PPC32 and PPC64
Changes in v2:
- Moved handling of unaligned strings outside of the main path as it is very unlikely.
- Removed the verification of the fourth byte in case none of the three first ones are NUL.
arch/powerpc/include/asm/asm-compat.h | 6 +++
arch/powerpc/include/asm/string.h | 1 +
arch/powerpc/lib/string.S | 81 +++++++++++++++++++++++++++++++++++
3 files changed, 88 insertions(+)
diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h
index 7f2a7702596c..fe2b459c8486 100644
--- a/arch/powerpc/include/asm/asm-compat.h
+++ b/arch/powerpc/include/asm/asm-compat.h
@@ -20,8 +20,11 @@
/* operations for longs and pointers */
#define PPC_LL stringify_in_c(ld)
+#define PPC_LLU stringify_in_c(ldu)
#define PPC_STL stringify_in_c(std)
#define PPC_STLU stringify_in_c(stdu)
+#define PPC_ROTLI stringify_in_c(rotldi)
+#define PPC_SRLI stringify_in_c(srdi)
#define PPC_LCMPI stringify_in_c(cmpdi)
#define PPC_LCMPLI stringify_in_c(cmpldi)
#define PPC_LCMP stringify_in_c(cmpd)
@@ -53,8 +56,11 @@
/* operations for longs and pointers */
#define PPC_LL stringify_in_c(lwz)
+#define PPC_LLU stringify_in_c(lwzu)
#define PPC_STL stringify_in_c(stw)
#define PPC_STLU stringify_in_c(stwu)
+#define PPC_ROTLI stringify_in_c(rotlwi)
+#define PPC_SRLI stringify_in_c(srwi)
#define PPC_LCMPI stringify_in_c(cmpwi)
#define PPC_LCMPLI stringify_in_c(cmplwi)
#define PPC_LCMP stringify_in_c(cmpw)
diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h
index 9b8cedf618f4..8fdcb532de72 100644
--- a/arch/powerpc/include/asm/string.h
+++ b/arch/powerpc/include/asm/string.h
@@ -13,6 +13,7 @@
#define __HAVE_ARCH_MEMCHR
#define __HAVE_ARCH_MEMSET16
#define __HAVE_ARCH_MEMCPY_FLUSHCACHE
+#define __HAVE_ARCH_STRLEN
extern char * strcpy(char *,const char *);
extern char * strncpy(char *,const char *, __kernel_size_t);
diff --git a/arch/powerpc/lib/string.S b/arch/powerpc/lib/string.S
index 4b41970e9ed8..1d0593cba9d4 100644
--- a/arch/powerpc/lib/string.S
+++ b/arch/powerpc/lib/string.S
@@ -67,3 +67,84 @@ _GLOBAL(memchr)
2: li r3,0
blr
EXPORT_SYMBOL(memchr)
+
+/*
+ * Algorigthm:
+ *
+ * 1) Given a word 'x', we can test to see if it contains any 0 bytes
+ * by subtracting 0x01010101, and seeing if any of the high bits of each
+ * byte changed from 0 to 1. This works because the least significant
+ * 0 byte must have had no incoming carry (otherwise it's not the least
+ * significant), so it is 0x00 - 0x01 == 0xff. For all other
+ * byte values, either they have the high bit set initially, or when
+ * 1 is subtracted you get a value in the range 0x00-0x7f, none of which
+ * have their high bit set. The expression here is
+ * (x - 0x01010101) & ~x & 0x80808080), which gives 0x00000000 when
+ * there were no 0x00 bytes in the word. You get 0x80 in bytes that
+ * match, but possibly false 0x80 matches in the next more significant
+ * byte to a true match due to carries. For little-endian this is
+ * of no consequence since the least significant match is the one
+ * we're interested in, but big-endian needs method 2 to find which
+ * byte matches.
+ * 2) Given a word 'x', we can test to see _which_ byte was zero by
+ * calculating ~(((x & ~0x80808080) - 0x80808080 - 1) | x | ~0x80808080).
+ * This produces 0x80 in each byte that was zero, and 0x00 in all
+ * the other bytes. The '| ~0x80808080' clears the low 7 bits in each
+ * byte, and the '| x' part ensures that bytes with the high bit set
+ * produce 0x00. The addition will carry into the high bit of each byte
+ * iff that byte had one of its low 7 bits set. We can then just see
+ * which was the most significant bit set and divide by 8 to find how
+ * many to add to the index.
+ * This is from the book 'The PowerPC Compiler Writer's Guide',
+ * by Steve Hoxey, Faraydon Karim, Bill Hay and Hank Warren.
+ */
+
+_GLOBAL(strlen)
+ andi. r9, r3, (SZL - 1)
+ lis r7, 0x0101
+ addi r10, r3, -SZL
+ addic r7, r7, 0x0101 /* r7 = 0x01010101 (lomagic) & clr CA */
+#ifdef CONFIG_PPC64
+ rldimi r7, r7, 32, 0 /* r7 = 0x0101010101010101 (lomagic) */
+#endif
+ bne- 1f
+2: PPC_ROTLI r6, r7, 31 /* r6 = 0x80808080(80808080) (himagic)*/
+ .balign IFETCH_ALIGN_BYTES
+3: PPC_LLU r9, SZL(r10)
+ /* ((x - lomagic) & ~x & himagic) == 0 means no byte in x is NUL */
+ subf r8, r7, r9
+ and. r8, r8, r6
+ beq+ 3b
+ andc. r8, r8, r9
+ beq+ 3b
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ andc r8, r9, r6
+ orc r9, r9, r6
+ subfe r8, r6, r8
+ nor r8, r8, r9
+ PPC_CNTLZL r8, r8
+ subf r3, r3, r10
+ PPC_SRLI r8, r8, 3
+ add r3, r3, r8
+#else
+ addi r9, r8, -1
+ addi r10, r10, (SZL - 1)
+ andc r8, r9, r8
+ PPC_CNTLZL r8, r8
+ subf r3, r3, r10
+ PPC_SRLI r8, r8, 3
+ subf r3, r8, r3
+#endif
+ blr
+
+1: lbz r9, SZL(r10)
+ addi r10, r10, 1
+ cmpwi cr1, r9, 0
+ andi. r9, r10, (SZL - 1)
+ beq cr1, 4f
+ bne 1b
+ b 2b
+4: addi r10, r10, (SZL - 1)
+ subf r3, r3, r10
+ blr
+EXPORT_SYMBOL(strlen)
--
2.13.3
^ permalink raw reply related
* [PATCH v6 4/4] selftests/powerpc: update strlen() test to test the new assembly function
From: Christophe Leroy @ 2018-06-12 9:14 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
wei.guo.simon, segher
Cc: linux-kernel, linuxppc-dev
In-Reply-To: <85de16f5629ac9f4a815230cced361908758b53a.1528791416.git.christophe.leroy@c-s.fr>
This patch modifies the test for testing the new assembly strlen() instead
of the generic strlen()
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
v6: added additional necessary defines in ppc_asm.h
v5: no change
v4: new
.../testing/selftests/powerpc/stringloops/Makefile | 3 +--
.../selftests/powerpc/stringloops/asm/cache.h | 1 +
.../selftests/powerpc/stringloops/asm/ppc_asm.h | 30 ++++++++++++++++++++++
.../testing/selftests/powerpc/stringloops/string.S | 1 +
4 files changed, 33 insertions(+), 2 deletions(-)
create mode 100644 tools/testing/selftests/powerpc/stringloops/asm/cache.h
create mode 120000 tools/testing/selftests/powerpc/stringloops/string.S
diff --git a/tools/testing/selftests/powerpc/stringloops/Makefile b/tools/testing/selftests/powerpc/stringloops/Makefile
index df663ee9ddb3..0c088a6d0369 100644
--- a/tools/testing/selftests/powerpc/stringloops/Makefile
+++ b/tools/testing/selftests/powerpc/stringloops/Makefile
@@ -10,8 +10,7 @@ $(OUTPUT)/memcmp_64: CFLAGS += -m64
$(OUTPUT)/memcmp_32: memcmp.c
$(OUTPUT)/memcmp_32: CFLAGS += -m32
-$(OUTPUT)/strlen: strlen.c string.o
-$(OUTPUT)/string.o: string.c
+$(OUTPUT)/strlen: strlen.c string.S
ASFLAGS = $(CFLAGS)
diff --git a/tools/testing/selftests/powerpc/stringloops/asm/cache.h b/tools/testing/selftests/powerpc/stringloops/asm/cache.h
new file mode 100644
index 000000000000..8a2840831122
--- /dev/null
+++ b/tools/testing/selftests/powerpc/stringloops/asm/cache.h
@@ -0,0 +1 @@
+#define IFETCH_ALIGN_BYTES 4
diff --git a/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h b/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h
index 136242ec4b0e..5226bd8bc39f 100644
--- a/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h
+++ b/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h
@@ -1,4 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0 */
+#if !defined(CONFIG_PPC64) && !defined(CONFIG_PPC32)
+#ifdef __powerpc64__
+#define CONFIG_PPC64
+#else
+#define CONFIG_PPC32
+#endif
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define CONFIG_CPU_LITTLE_ENDIAN
+#else
+#define CONFIG_CPU_BIG_ENDIAN
+#endif
+
#include <ppc-asm.h>
#ifndef r1
@@ -6,3 +20,19 @@
#endif
#define _GLOBAL(A) FUNC_START(test_ ## A)
+
+#ifdef __powerpc64__
+#define SZL 8
+#define PPC_LLU ldu
+#define PPC_LCMPI cmpldi
+#define PPC_ROTLI rotldi
+#define PPC_CNTLZL cntlzd
+#define PPC_SRLI srdi
+#else
+#define SZL 4
+#define PPC_LLU lwzu
+#define PPC_LCMPI cmplwi
+#define PPC_ROTLI rotlwi
+#define PPC_CNTLZL cntlzw
+#define PPC_SRLI srwi
+#endif
diff --git a/tools/testing/selftests/powerpc/stringloops/string.S b/tools/testing/selftests/powerpc/stringloops/string.S
new file mode 120000
index 000000000000..9f5babec7d21
--- /dev/null
+++ b/tools/testing/selftests/powerpc/stringloops/string.S
@@ -0,0 +1 @@
+../../../../../arch/powerpc/lib/string.S
\ No newline at end of file
--
2.13.3
^ permalink raw reply related
* [PATCH] powerpc/64s/radix: Fix radix_kvm_prefetch_workaround paca access of not possible CPU
From: Nicholas Piggin @ 2018-06-12 9:38 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nicholas Piggin, Pridhiviraj Paidipeddi, stable
If possible CPUs are limited (e.g., by kexec), then the kvm prefetch
workaround function can access the paca pointer for a !possible CPU.
Fixes: d2e60075a3d44 ("powerpc/64: Use array of paca pointers and allocate pacas individually")
Cc: stable@kernel.org
Reported-by: Pridhiviraj Paidipeddi <ppaidipe@linux.vnet.ibm.com>
Tested-by: Pridhiviraj Paidipeddi <ppaidipe@linux.vnet.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
[kdump still seems to have a problem upstream, but this solves one crash]
arch/powerpc/mm/tlb-radix.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/mm/tlb-radix.c b/arch/powerpc/mm/tlb-radix.c
index 67a6e86d3e7e..06ea845d8033 100644
--- a/arch/powerpc/mm/tlb-radix.c
+++ b/arch/powerpc/mm/tlb-radix.c
@@ -1043,6 +1043,8 @@ extern void radix_kvm_prefetch_workaround(struct mm_struct *mm)
for (; sib <= cpu_last_thread_sibling(cpu) && !flush; sib++) {
if (sib == cpu)
continue;
+ if (!cpu_possible(sib))
+ continue;
if (paca_ptrs[sib]->kvm_hstate.kvm_vcpu)
flush = true;
}
--
2.17.0
^ permalink raw reply related
* Re: [PATCH v5 1/4] resource: Move reparent_resources() to kernel/resource.c and make it public
From: Baoquan He @ 2018-06-12 9:38 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Linux Kernel Mailing List, Andrew Morton, Rob Herring,
Dan Williams, Nicolas Pitre, Josh Triplett, kbuild test robot,
Borislav Petkov, Patrik Jakobsson, David Airlie, KY Srinivasan,
Haiyang Zhang, Stephen Hemminger, Dmitry Torokhov, Frank Rowand,
Keith Busch, Jon Derrick, Lorenzo Pieralisi, Bjorn Helgaas,
Thomas Gleixner, brijesh.singh, Jérôme Glisse,
Tom Lendacky, Greg Kroah-Hartman, baiyaowei, richard.weiyang,
devel, linux-input, linux-nvdimm, devicetree, linux-pci,
Eric Biederman, Vivek Goyal, Dave Young, Yinghai Lu, kexec,
Michal Simek, David S. Miller, Chris Zankel, Max Filippov,
Gustavo Padovan, Maarten Lankhorst, Sean Paul, linux-parisc,
open list:LINUX FOR POWERPC PA SEMI PWRFICIENT,
Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
In-Reply-To: <CAHp75Vd6v4+RTq-5uw_BJpT6=w2KGjTfU+rEst6+8igs2cyntw@mail.gmail.com>
On 06/12/18 at 11:29am, Andy Shevchenko wrote:
> On Tue, Jun 12, 2018 at 6:28 AM, Baoquan He <bhe@redhat.com> wrote:
> > reparent_resources() is duplicated in arch/microblaze/pci/pci-common.c
> > and arch/powerpc/kernel/pci-common.c, so move it to kernel/resource.c
> > so that it's shared. Later its code also need be updated using list_head
> > to replace singly linked list.
>
> While this is a good deduplication of the code, some requirements for
> public functions would be good to satisfy.
>
> > +/*
> > + * Reparent resource children of pr that conflict with res
> > + * under res, and make res replace those children.
> > + */
>
> kernel doc format, though...
>
> > +static int reparent_resources(struct resource *parent,
> > + struct resource *res)
>
> ...is it really public with static keyword?!
Thanks for looking into this. This is a code bug, I copied and changed,
but forgot merging the changing to local commit. And the error reported
by test robot in patch 2 was changed too locally, forgot merging it to
patch. Will repost to address this.
>
>
>
> > +{
>
> > + for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
> > + if (p->end < res->start)
> > + continue;
> > + if (res->end < p->start)
> > + break;
>
> > + if (p->start < res->start || p->end > res->end)
> > + return -1; /* not completely contained */
>
> Usually we are expecting real eeror codes.
Hmm, I just copied it from arch/powerpc/kernel/pci-common.c. The
function interface expects an integer returned value, not sure what a
real error codes look like, could you give more hints? Will change
accordingly.
>
> > + if (firstpp == NULL)
> > + firstpp = pp;
> > + }
>
> > + if (firstpp == NULL)
> > + return -1; /* didn't find any conflicting entries? */
>
> Ditto.
>
> > +}
> > +EXPORT_SYMBOL(reparent_resources);
>
> --
> With Best Regards,
> Andy Shevchenko
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox