From 942cc40ae4354fee1e97137346434a2697d97e02 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 10 May 2018 16:54:39 +0100 Subject: macintosh/windfarm: fix spelling mistake: "ttarged" -> "ttarget" Trivial fix to spelling mistake in debug messages of a structure field name Signed-off-by: Colin Ian King Signed-off-by: Michael Ellerman --- drivers/macintosh/windfarm_pm121.c | 2 +- drivers/macintosh/windfarm_pm81.c | 2 +- drivers/macintosh/windfarm_pm91.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/windfarm_pm121.c b/drivers/macintosh/windfarm_pm121.c index 4d72d8f58cb6..97634e030991 100644 --- a/drivers/macintosh/windfarm_pm121.c +++ b/drivers/macintosh/windfarm_pm121.c @@ -710,7 +710,7 @@ static void pm121_create_cpu_fans(void) wf_cpu_pid_init(&pm121_cpu_state->pid, &pid_param); pr_debug("pm121: CPU Fan control initialized.\n"); - pr_debug(" ttarged=%d.%03d, tmax=%d.%03d, min=%d RPM, max=%d RPM,\n", + pr_debug(" ttarget=%d.%03d, tmax=%d.%03d, min=%d RPM, max=%d RPM,\n", FIX32TOPRINT(pid_param.ttarget), FIX32TOPRINT(pid_param.tmax), pid_param.min, pid_param.max); diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c index d9ea45581b9e..346c91744442 100644 --- a/drivers/macintosh/windfarm_pm81.c +++ b/drivers/macintosh/windfarm_pm81.c @@ -455,7 +455,7 @@ static void wf_smu_create_cpu_fans(void) wf_cpu_pid_init(&wf_smu_cpu_fans->pid, &pid_param); DBG("wf: CPU Fan control initialized.\n"); - DBG(" ttarged=%d.%03d, tmax=%d.%03d, min=%d RPM, max=%d RPM\n", + DBG(" ttarget=%d.%03d, tmax=%d.%03d, min=%d RPM, max=%d RPM\n", FIX32TOPRINT(pid_param.ttarget), FIX32TOPRINT(pid_param.tmax), pid_param.min, pid_param.max); diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c index 7fd73dcb2b0a..a8a47c62a74b 100644 --- a/drivers/macintosh/windfarm_pm91.c +++ b/drivers/macintosh/windfarm_pm91.c @@ -200,7 +200,7 @@ static void wf_smu_create_cpu_fans(void) wf_cpu_pid_init(&wf_smu_cpu_fans->pid, &pid_param); DBG("wf: CPU Fan control initialized.\n"); - DBG(" ttarged=%d.%03d, tmax=%d.%03d, min=%d RPM, max=%d RPM\n", + DBG(" ttarget=%d.%03d, tmax=%d.%03d, min=%d RPM, max=%d RPM\n", FIX32TOPRINT(pid_param.ttarget), FIX32TOPRINT(pid_param.tmax), pid_param.min, pid_param.max); -- cgit v1.2.3 From 3c8c049aa7bdffaab2e53401fd5270a3acc32631 Mon Sep 17 00:00:00 2001 From: Shilpasri G Bhat Date: Mon, 7 May 2018 15:55:37 +0530 Subject: hwmon: (ibmpowernv): Add support to read 64 bit sensors The firmware has supported for reading sensor values of size u32. This patch adds support to use newer firmware functions which allows to read the sensors of size u64. Signed-off-by: Shilpasri G Bhat Acked-by: Guenter Roeck Signed-off-by: Michael Ellerman --- drivers/hwmon/ibmpowernv.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c index 5ccdd0b52650..74d9b5ae55ec 100644 --- a/drivers/hwmon/ibmpowernv.c +++ b/drivers/hwmon/ibmpowernv.c @@ -101,9 +101,10 @@ static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr, struct sensor_data *sdata = container_of(devattr, struct sensor_data, dev_attr); ssize_t ret; - u32 x; + u64 x; + + ret = opal_get_sensor_data_u64(sdata->id, &x); - ret = opal_get_sensor_data(sdata->id, &x); if (ret) return ret; @@ -114,7 +115,7 @@ static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr, else if (sdata->type == POWER_INPUT) x *= 1000000; - return sprintf(buf, "%u\n", x); + return sprintf(buf, "%llu\n", x); } static ssize_t show_label(struct device *dev, struct device_attribute *devattr, -- cgit v1.2.3 From 43d2974b66d916a6df16e536da542e3a65aab7b9 Mon Sep 17 00:00:00 2001 From: Shilpasri G Bhat Date: Mon, 7 May 2018 15:55:38 +0530 Subject: hwmon: (ibmpowernv) Add energy sensors This patch exports the accumulated power numbers of each power sensor maintained by OCC. Signed-off-by: Shilpasri G Bhat Acked-by: Guenter Roeck Signed-off-by: Michael Ellerman --- drivers/hwmon/ibmpowernv.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/ibmpowernv.c b/drivers/hwmon/ibmpowernv.c index 74d9b5ae55ec..0298745d46e4 100644 --- a/drivers/hwmon/ibmpowernv.c +++ b/drivers/hwmon/ibmpowernv.c @@ -51,6 +51,7 @@ enum sensors { POWER_SUPPLY, POWER_INPUT, CURRENT, + ENERGY, MAX_SENSOR_TYPE, }; @@ -78,6 +79,7 @@ static struct sensor_group { { "in" }, { "power" }, { "curr" }, + { "energy" }, }; struct sensor_data { -- cgit v1.2.3 From d8731527acee53b4d46d59ff0b5fc36931ad0451 Mon Sep 17 00:00:00 2001 From: Mathieu Malaterre Date: Fri, 13 Apr 2018 20:41:43 +0200 Subject: powerpc/sparse: Fix plain integer as NULL pointer warning Trivial fix to remove the following sparse warnings: arch/powerpc/kernel/module_32.c:112:74: warning: Using plain integer as NULL pointer arch/powerpc/kernel/module_32.c:117:74: warning: Using plain integer as NULL pointer drivers/macintosh/via-pmu.c:1155:28: warning: Using plain integer as NULL pointer drivers/macintosh/via-pmu.c:1230:20: warning: Using plain integer as NULL pointer drivers/macintosh/via-pmu.c:1385:36: warning: Using plain integer as NULL pointer drivers/macintosh/via-pmu.c:1752:23: warning: Using plain integer as NULL pointer drivers/macintosh/via-pmu.c:2084:19: warning: Using plain integer as NULL pointer drivers/macintosh/via-pmu.c:2110:32: warning: Using plain integer as NULL pointer drivers/macintosh/via-pmu.c:2167:19: warning: Using plain integer as NULL pointer drivers/macintosh/via-pmu.c:2183:19: warning: Using plain integer as NULL pointer drivers/macintosh/via-pmu.c:277:20: warning: Using plain integer as NULL pointer arch/powerpc/platforms/powermac/setup.c:155:67: warning: Using plain integer as NULL pointer arch/powerpc/platforms/powermac/setup.c:247:27: warning: Using plain integer as NULL pointer arch/powerpc/platforms/powermac/setup.c:249:27: warning: Using plain integer as NULL pointer arch/powerpc/platforms/powermac/setup.c:252:37: warning: Using plain integer as NULL pointer arch/powerpc/mm/tlb_hash32.c:127:21: warning: Using plain integer as NULL pointer arch/powerpc/mm/tlb_hash32.c:148:21: warning: Using plain integer as NULL pointer arch/powerpc/mm/tlb_hash32.c:44:21: warning: Using plain integer as NULL pointer arch/powerpc/mm/tlb_hash32.c:57:21: warning: Using plain integer as NULL pointer arch/powerpc/mm/tlb_hash32.c:87:21: warning: Using plain integer as NULL pointer arch/powerpc/kernel/btext.c:160:31: warning: Using plain integer as NULL pointer arch/powerpc/kernel/btext.c:167:22: warning: Using plain integer as NULL pointer arch/powerpc/kernel/btext.c:274:21: warning: Using plain integer as NULL pointer arch/powerpc/kernel/btext.c:285:31: warning: Using plain integer as NULL pointer arch/powerpc/include/asm/hugetlb.h:204:16: warning: Using plain integer as NULL pointer arch/powerpc/mm/ppc_mmu_32.c:170:21: warning: Using plain integer as NULL pointer arch/powerpc/platforms/powermac/pci.c:1227:23: warning: Using plain integer as NULL pointer arch/powerpc/platforms/powermac/pci.c:65:24: warning: Using plain integer as NULL pointer Also use `--fix` command line option from `script/checkpatch --strict` to remove the following: CHECK: Comparison to NULL could be written "!dispDeviceBase" #72: FILE: arch/powerpc/kernel/btext.c:160: + if (dispDeviceBase == NULL) CHECK: Comparison to NULL could be written "!vbase" #80: FILE: arch/powerpc/kernel/btext.c:167: + if (vbase == NULL) CHECK: Comparison to NULL could be written "!base" #89: FILE: arch/powerpc/kernel/btext.c:274: + if (base == NULL) CHECK: Comparison to NULL could be written "!dispDeviceBase" #98: FILE: arch/powerpc/kernel/btext.c:285: + if (dispDeviceBase == NULL) CHECK: Comparison to NULL could be written "strstr" #117: FILE: arch/powerpc/kernel/module_32.c:117: + if (strstr(secstrings + sechdrs[i].sh_name, ".debug") != NULL) CHECK: Comparison to NULL could be written "!Hash" #130: FILE: arch/powerpc/mm/ppc_mmu_32.c:170: + if (Hash == NULL) CHECK: Comparison to NULL could be written "Hash" #143: FILE: arch/powerpc/mm/tlb_hash32.c:44: + if (Hash != NULL) { CHECK: Comparison to NULL could be written "!Hash" #152: FILE: arch/powerpc/mm/tlb_hash32.c:57: + if (Hash == NULL) { CHECK: Comparison to NULL could be written "!Hash" #161: FILE: arch/powerpc/mm/tlb_hash32.c:87: + if (Hash == NULL) { CHECK: Comparison to NULL could be written "!Hash" #170: FILE: arch/powerpc/mm/tlb_hash32.c:127: + if (Hash == NULL) { CHECK: Comparison to NULL could be written "!Hash" #179: FILE: arch/powerpc/mm/tlb_hash32.c:148: + if (Hash == NULL) { ERROR: space required after that ';' (ctx:VxV) #192: FILE: arch/powerpc/platforms/powermac/pci.c:65: + for (; node != NULL;node = node->sibling) { CHECK: Comparison to NULL could be written "node" #192: FILE: arch/powerpc/platforms/powermac/pci.c:65: + for (; node != NULL;node = node->sibling) { CHECK: Comparison to NULL could be written "!region" #201: FILE: arch/powerpc/platforms/powermac/pci.c:1227: + if (region == NULL) CHECK: Comparison to NULL could be written "of_get_property" #214: FILE: arch/powerpc/platforms/powermac/setup.c:155: + if (of_get_property(np, "cache-unified", NULL) != NULL && dc) { CHECK: Comparison to NULL could be written "!np" #223: FILE: arch/powerpc/platforms/powermac/setup.c:247: + if (np == NULL) CHECK: Comparison to NULL could be written "np" #226: FILE: arch/powerpc/platforms/powermac/setup.c:249: + if (np != NULL) { CHECK: Comparison to NULL could be written "l2cr" #230: FILE: arch/powerpc/platforms/powermac/setup.c:252: + if (l2cr != NULL) { CHECK: Comparison to NULL could be written "via" #243: FILE: drivers/macintosh/via-pmu.c:277: + if (via != NULL) CHECK: Comparison to NULL could be written "current_req" #252: FILE: drivers/macintosh/via-pmu.c:1155: + if (current_req != NULL) { CHECK: Comparison to NULL could be written "!req" #261: FILE: drivers/macintosh/via-pmu.c:1230: + if (req == NULL || pmu_state != idle CHECK: Comparison to NULL could be written "!req" #270: FILE: drivers/macintosh/via-pmu.c:1385: + if (req == NULL) { CHECK: Comparison to NULL could be written "!pp" #288: FILE: drivers/macintosh/via-pmu.c:2084: + if (pp == NULL) CHECK: Comparison to NULL could be written "!pp" #297: FILE: drivers/macintosh/via-pmu.c:2110: + if (count < 1 || pp == NULL) CHECK: Comparison to NULL could be written "!pp" #306: FILE: drivers/macintosh/via-pmu.c:2167: + if (pp == NULL) CHECK: Comparison to NULL could be written "pp" #315: FILE: drivers/macintosh/via-pmu.c:2183: + if (pp != NULL) { Link: https://github.com/linuxppc/linux/issues/37 Signed-off-by: Mathieu Malaterre Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/hugetlb.h | 2 +- arch/powerpc/kernel/btext.c | 8 ++++---- arch/powerpc/kernel/module_32.c | 4 ++-- arch/powerpc/mm/ppc_mmu_32.c | 2 +- arch/powerpc/mm/tlb_hash32.c | 10 +++++----- arch/powerpc/platforms/powermac/pci.c | 4 ++-- arch/powerpc/platforms/powermac/setup.c | 8 ++++---- drivers/macintosh/via-pmu.c | 18 +++++++++--------- 8 files changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 78540c074d70..96444bc08034 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -202,7 +202,7 @@ static inline void flush_hugetlb_page(struct vm_area_struct *vma, static inline pte_t *hugepte_offset(hugepd_t hpd, unsigned long addr, unsigned pdshift) { - return 0; + return NULL; } #endif /* CONFIG_HUGETLB_PAGE */ diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index 6537cba1a758..54403144623f 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c @@ -157,14 +157,14 @@ void btext_map(void) /* By default, we are no longer mapped */ boot_text_mapped = 0; - if (dispDeviceBase == 0) + if (!dispDeviceBase) return; base = ((unsigned long) dispDeviceBase) & 0xFFFFF000UL; offset = ((unsigned long) dispDeviceBase) - base; size = dispDeviceRowBytes * dispDeviceRect[3] + offset + dispDeviceRect[0]; vbase = __ioremap(base, size, pgprot_val(pgprot_noncached_wc(__pgprot(0)))); - if (vbase == 0) + if (!vbase) return; logicalDisplayBase = vbase + offset; boot_text_mapped = 1; @@ -270,7 +270,7 @@ static unsigned char * calc_base(int x, int y) unsigned char *base; base = logicalDisplayBase; - if (base == 0) + if (!base) base = dispDeviceBase; base += (x + dispDeviceRect[0]) * (dispDeviceDepth >> 3); base += (y + dispDeviceRect[1]) * dispDeviceRowBytes; @@ -281,7 +281,7 @@ static unsigned char * calc_base(int x, int y) void btext_update_display(unsigned long phys, int width, int height, int depth, int pitch) { - if (dispDeviceBase == 0) + if (!dispDeviceBase) return; /* check it's the same frame buffer (within 256MB) */ diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c index 5a7a78f12562..88d83771f462 100644 --- a/arch/powerpc/kernel/module_32.c +++ b/arch/powerpc/kernel/module_32.c @@ -109,12 +109,12 @@ static unsigned long get_plt_size(const Elf32_Ehdr *hdr, for (i = 1; i < hdr->e_shnum; i++) { /* If it's called *.init*, and we're not init, we're not interested */ - if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0) + if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != NULL) != is_init) continue; /* We don't want to look at debug sections. */ - if (strstr(secstrings + sechdrs[i].sh_name, ".debug") != 0) + if (strstr(secstrings + sechdrs[i].sh_name, ".debug")) continue; if (sechdrs[i].sh_type == SHT_RELA) { diff --git a/arch/powerpc/mm/ppc_mmu_32.c b/arch/powerpc/mm/ppc_mmu_32.c index 2a049fb8523d..bea6c544e38f 100644 --- a/arch/powerpc/mm/ppc_mmu_32.c +++ b/arch/powerpc/mm/ppc_mmu_32.c @@ -167,7 +167,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, { pmd_t *pmd; - if (Hash == 0) + if (!Hash) return; pmd = pmd_offset(pud_offset(pgd_offset(mm, ea), ea), ea); if (!pmd_none(*pmd)) diff --git a/arch/powerpc/mm/tlb_hash32.c b/arch/powerpc/mm/tlb_hash32.c index 702d7689d714..cf8472cf3d59 100644 --- a/arch/powerpc/mm/tlb_hash32.c +++ b/arch/powerpc/mm/tlb_hash32.c @@ -41,7 +41,7 @@ void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, unsigned long addr) { unsigned long ptephys; - if (Hash != 0) { + if (Hash) { ptephys = __pa(ptep) & PAGE_MASK; flush_hash_pages(mm->context.id, addr, ptephys, 1); } @@ -54,7 +54,7 @@ EXPORT_SYMBOL(flush_hash_entry); */ void tlb_flush(struct mmu_gather *tlb) { - if (Hash == 0) { + if (!Hash) { /* * 603 needs to flush the whole TLB here since * it doesn't use a hash table. @@ -84,7 +84,7 @@ static void flush_range(struct mm_struct *mm, unsigned long start, int count; unsigned int ctx = mm->context.id; - if (Hash == 0) { + if (!Hash) { _tlbia(); return; } @@ -124,7 +124,7 @@ void flush_tlb_mm(struct mm_struct *mm) { struct vm_area_struct *mp; - if (Hash == 0) { + if (!Hash) { _tlbia(); return; } @@ -145,7 +145,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) struct mm_struct *mm; pmd_t *pmd; - if (Hash == 0) { + if (!Hash) { _tlbie(vmaddr); return; } diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 0b8174a79993..df762bb3c735 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -62,7 +62,7 @@ struct device_node *k2_skiplist[2]; static int __init fixup_one_level_bus_range(struct device_node *node, int higher) { - for (; node != 0;node = node->sibling) { + for (; node; node = node->sibling) { const int * bus_range; const unsigned int *class_code; int len; @@ -1219,7 +1219,7 @@ static void fixup_u4_pcie(struct pci_dev* dev) region = r; } /* Nothing found, bail */ - if (region == 0) + if (!region) return; /* Print things out */ diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index ab668cb72263..f40e87ca180b 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -152,7 +152,7 @@ static void pmac_show_cpuinfo(struct seq_file *m) of_get_property(np, "d-cache-size", NULL); seq_printf(m, "L2 cache\t:"); has_l2cache = 1; - if (of_get_property(np, "cache-unified", NULL) != 0 && dc) { + if (of_get_property(np, "cache-unified", NULL) && dc) { seq_printf(m, " %dK unified", *dc / 1024); } else { if (ic) @@ -244,12 +244,12 @@ static void __init l2cr_init(void) /* Checks "l2cr-value" property in the registry */ if (cpu_has_feature(CPU_FTR_L2CR)) { struct device_node *np = of_find_node_by_name(NULL, "cpus"); - if (np == 0) + if (!np) np = of_find_node_by_type(NULL, "cpu"); - if (np != 0) { + if (np) { const unsigned int *l2cr = of_get_property(np, "l2cr-value", NULL); - if (l2cr != 0) { + if (l2cr) { ppc_override_l2cr = 1; ppc_override_l2cr_value = *l2cr; _set_L2CR(0); diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 433dbeddfcf9..a3b6a4a703ab 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -274,7 +274,7 @@ int __init find_via_pmu(void) u64 taddr; const u32 *reg; - if (via != 0) + if (via) return 1; vias = of_find_node_by_name(NULL, "via-pmu"); if (vias == NULL) @@ -1152,7 +1152,7 @@ pmu_queue_request(struct adb_request *req) req->complete = 0; spin_lock_irqsave(&pmu_lock, flags); - if (current_req != 0) { + if (current_req) { last_req->next = req; last_req = req; } else { @@ -1227,7 +1227,7 @@ pmu_start(void) /* assert pmu_state == idle */ /* get the packet to send */ req = current_req; - if (req == 0 || pmu_state != idle + if (!req || pmu_state != idle || (/*req->reply_expected && */req_awaiting_reply)) return; @@ -1382,7 +1382,7 @@ next: if ((1 << pirq) & PMU_INT_ADB) { if ((data[0] & PMU_INT_ADB_AUTO) == 0) { struct adb_request *req = req_awaiting_reply; - if (req == 0) { + if (!req) { printk(KERN_ERR "PMU: extra ADB reply\n"); return; } @@ -1749,7 +1749,7 @@ pmu_shutdown(void) int pmu_present(void) { - return via != 0; + return via != NULL; } #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) @@ -2081,7 +2081,7 @@ pmu_open(struct inode *inode, struct file *file) unsigned long flags; pp = kmalloc(sizeof(struct pmu_private), GFP_KERNEL); - if (pp == 0) + if (!pp) return -ENOMEM; pp->rb_get = pp->rb_put = 0; spin_lock_init(&pp->lock); @@ -2107,7 +2107,7 @@ pmu_read(struct file *file, char __user *buf, unsigned long flags; int ret = 0; - if (count < 1 || pp == 0) + if (count < 1 || !pp) return -EINVAL; if (!access_ok(VERIFY_WRITE, buf, count)) return -EFAULT; @@ -2164,7 +2164,7 @@ pmu_fpoll(struct file *filp, poll_table *wait) __poll_t mask = 0; unsigned long flags; - if (pp == 0) + if (!pp) return 0; poll_wait(filp, &pp->wait, wait); spin_lock_irqsave(&pp->lock, flags); @@ -2180,7 +2180,7 @@ pmu_release(struct inode *inode, struct file *file) struct pmu_private *pp = file->private_data; unsigned long flags; - if (pp != 0) { + if (pp) { file->private_data = NULL; spin_lock_irqsave(&all_pvt_lock, flags); list_del(&pp->list); -- cgit v1.2.3 From b6c84ba22ff3a198eb8d5552cf9b8fda1d792e54 Mon Sep 17 00:00:00 2001 From: Vaibhav Jain Date: Fri, 18 May 2018 15:12:23 +0530 Subject: cxl: Disable prefault_mode in Radix mode Currently we see a kernel-oops reported on Power-9 while attaching a context to an AFU, with radix-mode and sysfs attr 'prefault_mode' set to anything other than 'none'. The backtrace of the oops is of this form: Unable to handle kernel paging request for data at address 0x00000080 Faulting instruction address: 0xc00800000bcf3b20 cpu 0x1: Vector: 300 (Data Access) at [c00000037f003800] pc: c00800000bcf3b20: cxl_load_segment+0x178/0x290 [cxl] lr: c00800000bcf39f0: cxl_load_segment+0x48/0x290 [cxl] sp: c00000037f003a80 msr: 9000000000009033 dar: 80 dsisr: 40000000 current = 0xc00000037f280000 paca = 0xc0000003ffffe600 softe: 3 irq_happened: 0x01 pid = 3529, comm = afp_no_int cxl_prefault+0xfc/0x248 [cxl] process_element_entry_psl9+0xd8/0x1a0 [cxl] cxl_attach_dedicated_process_psl9+0x44/0x130 [cxl] native_attach_process+0xc0/0x130 [cxl] afu_ioctl+0x3f4/0x5e0 [cxl] do_vfs_ioctl+0xdc/0x890 ksys_ioctl+0x68/0xf0 sys_ioctl+0x40/0xa0 system_call+0x58/0x6c The issue is caused as on Power-8 the AFU attr 'prefault_mode' was used to improve initial storage fault performance by prefaulting process segments. However on Power-9 with radix mode we don't have Storage-Segments that we can prefault. Also prefaulting process Pages will be too costly and fine-grained. Hence, since the prefaulting mechanism doesn't makes sense of radix-mode, this patch updates prefault_mode_store() to not allow any other value apart from CXL_PREFAULT_NONE when radix mode is enabled. Fixes: f24be42aab37 ("cxl: Add psl9 specific code") Cc: stable@vger.kernel.org # v4.12+ Signed-off-by: Vaibhav Jain Acked-by: Frederic Barrat Acked-by: Andrew Donnellan Signed-off-by: Michael Ellerman --- Documentation/ABI/testing/sysfs-class-cxl | 4 +++- drivers/misc/cxl/sysfs.c | 16 ++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl index 640f65e79ef1..267920a1874b 100644 --- a/Documentation/ABI/testing/sysfs-class-cxl +++ b/Documentation/ABI/testing/sysfs-class-cxl @@ -69,7 +69,9 @@ Date: September 2014 Contact: linuxppc-dev@lists.ozlabs.org Description: read/write Set the mode for prefaulting in segments into the segment table - when performing the START_WORK ioctl. Possible values: + when performing the START_WORK ioctl. Only applicable when + running under hashed page table mmu. + Possible values: none: No prefaulting (default) work_element_descriptor: Treat the work element descriptor as an effective address and diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c index 95285b7f636f..90aa4eee8ccd 100644 --- a/drivers/misc/cxl/sysfs.c +++ b/drivers/misc/cxl/sysfs.c @@ -343,12 +343,20 @@ static ssize_t prefault_mode_store(struct device *device, struct cxl_afu *afu = to_cxl_afu(device); enum prefault_modes mode = -1; - if (!strncmp(buf, "work_element_descriptor", 23)) - mode = CXL_PREFAULT_WED; - if (!strncmp(buf, "all", 3)) - mode = CXL_PREFAULT_ALL; if (!strncmp(buf, "none", 4)) mode = CXL_PREFAULT_NONE; + else { + if (!radix_enabled()) { + + /* only allowed when not in radix mode */ + if (!strncmp(buf, "work_element_descriptor", 23)) + mode = CXL_PREFAULT_WED; + if (!strncmp(buf, "all", 3)) + mode = CXL_PREFAULT_ALL; + } else { + dev_err(device, "Cannot prefault with radix enabled\n"); + } + } if (mode == -1) return -EINVAL; -- cgit v1.2.3 From 9a6d2022bacd8fca0be6297459a02dfd28dad6ba Mon Sep 17 00:00:00 2001 From: Vaibhav Jain Date: Tue, 17 Apr 2018 10:41:02 +0530 Subject: cxl: Configure PSL to not use APC virtual machines APC virtual machines arent used on POWER-9 chips and are already disabled in on-chip CAPP. They also need to be disabled on the PSL via 'PSL Data Send Control Register' by setting bit(47). This forces the PSL to send commands to CAPP with queue.id == 0. Fixes: 5632874311db ("cxl: Add support for POWER9 DD2") Cc: stable@vger.kernel.org # v4.15+ Signed-off-by: Vaibhav Jain Acked-by: Andrew Donnellan Reviewed-by: Alastair D'Silva Reviewed-by: Christophe Lombard Signed-off-by: Michael Ellerman --- drivers/misc/cxl/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c index 83f1d08058fc..2e8b187956bc 100644 --- a/drivers/misc/cxl/pci.c +++ b/drivers/misc/cxl/pci.c @@ -514,9 +514,9 @@ static int init_implementation_adapter_regs_psl9(struct cxl *adapter, cxl_p1_write(adapter, CXL_PSL9_FIR_CNTL, psl_fircntl); /* Setup the PSL to transmit packets on the PCIe before the - * CAPP is enabled + * CAPP is enabled. Make sure that CAPP virtual machines are disabled */ - cxl_p1_write(adapter, CXL_PSL9_DSNDCTL, 0x0001001000002A10ULL); + cxl_p1_write(adapter, CXL_PSL9_DSNDCTL, 0x0001001000012A10ULL); /* * A response to an ASB_Notify request is returned by the -- cgit v1.2.3 From 19df39581ce99eb1fcfb119945810c9c5bc3f8d4 Mon Sep 17 00:00:00 2001 From: Alastair D'Silva Date: Fri, 11 May 2018 16:13:00 +1000 Subject: ocxl: Rename pnv_ocxl_spa_remove_pe to clarify it's action The function removes the process element from NPU cache. Signed-off-by: Alastair D'Silva Acked-by: Frederic Barrat Acked-by: Andrew Donnellan Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/pnv-ocxl.h | 2 +- arch/powerpc/platforms/powernv/ocxl.c | 4 ++-- drivers/misc/ocxl/link.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/arch/powerpc/include/asm/pnv-ocxl.h b/arch/powerpc/include/asm/pnv-ocxl.h index f6945d3bc971..208b5503f4ed 100644 --- a/arch/powerpc/include/asm/pnv-ocxl.h +++ b/arch/powerpc/include/asm/pnv-ocxl.h @@ -28,7 +28,7 @@ extern int pnv_ocxl_map_xsl_regs(struct pci_dev *dev, void __iomem **dsisr, extern int pnv_ocxl_spa_setup(struct pci_dev *dev, void *spa_mem, int PE_mask, void **platform_data); extern void pnv_ocxl_spa_release(void *platform_data); -extern int pnv_ocxl_spa_remove_pe(void *platform_data, int pe_handle); +extern int pnv_ocxl_spa_remove_pe_from_cache(void *platform_data, int pe_handle); extern int pnv_ocxl_alloc_xive_irq(u32 *irq, u64 *trigger_addr); extern void pnv_ocxl_free_xive_irq(u32 irq); diff --git a/arch/powerpc/platforms/powernv/ocxl.c b/arch/powerpc/platforms/powernv/ocxl.c index fa9b53af3c7b..8c65aacda9c8 100644 --- a/arch/powerpc/platforms/powernv/ocxl.c +++ b/arch/powerpc/platforms/powernv/ocxl.c @@ -475,7 +475,7 @@ void pnv_ocxl_spa_release(void *platform_data) } EXPORT_SYMBOL_GPL(pnv_ocxl_spa_release); -int pnv_ocxl_spa_remove_pe(void *platform_data, int pe_handle) +int pnv_ocxl_spa_remove_pe_from_cache(void *platform_data, int pe_handle) { struct spa_data *data = (struct spa_data *) platform_data; int rc; @@ -483,7 +483,7 @@ int pnv_ocxl_spa_remove_pe(void *platform_data, int pe_handle) rc = opal_npu_spa_clear_cache(data->phb_opal_id, data->bdfn, pe_handle); return rc; } -EXPORT_SYMBOL_GPL(pnv_ocxl_spa_remove_pe); +EXPORT_SYMBOL_GPL(pnv_ocxl_spa_remove_pe_from_cache); int pnv_ocxl_alloc_xive_irq(u32 *irq, u64 *trigger_addr) { diff --git a/drivers/misc/ocxl/link.c b/drivers/misc/ocxl/link.c index f30790582dc0..656e8610eec2 100644 --- a/drivers/misc/ocxl/link.c +++ b/drivers/misc/ocxl/link.c @@ -599,7 +599,7 @@ int ocxl_link_remove_pe(void *link_handle, int pasid) * On powerpc, the entry needs to be cleared from the context * cache of the NPU. */ - rc = pnv_ocxl_spa_remove_pe(link->platform_data, pe_handle); + rc = pnv_ocxl_spa_remove_pe_from_cache(link->platform_data, pe_handle); WARN_ON(rc); pe_data = radix_tree_delete(&spa->pe_tree, pe_handle); -- cgit v1.2.3 From e948e06fc63a1c1e36ec4c8e5c510b881ff19c26 Mon Sep 17 00:00:00 2001 From: Alastair D'Silva Date: Fri, 11 May 2018 16:13:01 +1000 Subject: ocxl: Expose the thread_id needed for wait on POWER9 In order to successfully issue as_notify, an AFU needs to know the TID to notify, which in turn means that this information should be available in userspace so it can be communicated to the AFU. Signed-off-by: Alastair D'Silva Acked-by: Andrew Donnellan Signed-off-by: Michael Ellerman --- drivers/misc/ocxl/context.c | 5 +++- drivers/misc/ocxl/file.c | 53 +++++++++++++++++++++++++++++++++++++++ drivers/misc/ocxl/link.c | 36 ++++++++++++++++++++++++++ drivers/misc/ocxl/ocxl_internal.h | 1 + include/misc/ocxl.h | 9 +++++++ include/uapi/misc/ocxl.h | 8 ++++++ 6 files changed, 111 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/ocxl/context.c b/drivers/misc/ocxl/context.c index 909e8807824a..95f74623113e 100644 --- a/drivers/misc/ocxl/context.c +++ b/drivers/misc/ocxl/context.c @@ -34,6 +34,8 @@ int ocxl_context_init(struct ocxl_context *ctx, struct ocxl_afu *afu, mutex_init(&ctx->xsl_error_lock); mutex_init(&ctx->irq_lock); idr_init(&ctx->irq_idr); + ctx->tidr = 0; + /* * Keep a reference on the AFU to make sure it's valid for the * duration of the life of the context @@ -65,6 +67,7 @@ int ocxl_context_attach(struct ocxl_context *ctx, u64 amr) { int rc; + // Locks both status & tidr mutex_lock(&ctx->status_mutex); if (ctx->status != OPENED) { rc = -EIO; @@ -72,7 +75,7 @@ int ocxl_context_attach(struct ocxl_context *ctx, u64 amr) } rc = ocxl_link_add_pe(ctx->afu->fn->link, ctx->pasid, - current->mm->context.id, 0, amr, current->mm, + current->mm->context.id, ctx->tidr, amr, current->mm, xsl_fault_error, ctx); if (rc) goto out; diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c index 038509e5d031..eb409a469f21 100644 --- a/drivers/misc/ocxl/file.c +++ b/drivers/misc/ocxl/file.c @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include "ocxl_internal.h" @@ -123,11 +125,55 @@ static long afu_ioctl_get_metadata(struct ocxl_context *ctx, return 0; } +#ifdef CONFIG_PPC64 +static long afu_ioctl_enable_p9_wait(struct ocxl_context *ctx, + struct ocxl_ioctl_p9_wait __user *uarg) +{ + struct ocxl_ioctl_p9_wait arg; + + memset(&arg, 0, sizeof(arg)); + + if (cpu_has_feature(CPU_FTR_P9_TIDR)) { + enum ocxl_context_status status; + + // Locks both status & tidr + mutex_lock(&ctx->status_mutex); + if (!ctx->tidr) { + if (set_thread_tidr(current)) + return -ENOENT; + + ctx->tidr = current->thread.tidr; + } + + status = ctx->status; + mutex_unlock(&ctx->status_mutex); + + if (status == ATTACHED) { + int rc; + struct link *link = ctx->afu->fn->link; + + rc = ocxl_link_update_pe(link, ctx->pasid, ctx->tidr); + if (rc) + return rc; + } + + arg.thread_id = ctx->tidr; + } else + return -ENOENT; + + if (copy_to_user(uarg, &arg, sizeof(arg))) + return -EFAULT; + + return 0; +} +#endif + #define CMD_STR(x) (x == OCXL_IOCTL_ATTACH ? "ATTACH" : \ x == OCXL_IOCTL_IRQ_ALLOC ? "IRQ_ALLOC" : \ x == OCXL_IOCTL_IRQ_FREE ? "IRQ_FREE" : \ x == OCXL_IOCTL_IRQ_SET_FD ? "IRQ_SET_FD" : \ x == OCXL_IOCTL_GET_METADATA ? "GET_METADATA" : \ + x == OCXL_IOCTL_ENABLE_P9_WAIT ? "ENABLE_P9_WAIT" : \ "UNKNOWN") static long afu_ioctl(struct file *file, unsigned int cmd, @@ -186,6 +232,13 @@ static long afu_ioctl(struct file *file, unsigned int cmd, (struct ocxl_ioctl_metadata __user *) args); break; +#ifdef CONFIG_PPC64 + case OCXL_IOCTL_ENABLE_P9_WAIT: + rc = afu_ioctl_enable_p9_wait(ctx, + (struct ocxl_ioctl_p9_wait __user *) args); + break; +#endif + default: rc = -EINVAL; } diff --git a/drivers/misc/ocxl/link.c b/drivers/misc/ocxl/link.c index 656e8610eec2..88876ae8f330 100644 --- a/drivers/misc/ocxl/link.c +++ b/drivers/misc/ocxl/link.c @@ -544,6 +544,42 @@ unlock: } 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 spa *spa = link->spa; + struct ocxl_process_element *pe; + int pe_handle, rc; + + if (pasid > SPA_PASID_MAX) + return -EINVAL; + + pe_handle = pasid & SPA_PE_MASK; + pe = spa->spa_mem + pe_handle; + + mutex_lock(&spa->spa_lock); + + pe->tid = tid; + + /* + * The barrier makes sure the PE is updated + * before we clear the NPU context cache below, so that the + * old PE cannot be reloaded erroneously. + */ + mb(); + + /* + * hook to platform code + * On powerpc, the entry needs to be cleared from the context + * cache of the NPU. + */ + rc = pnv_ocxl_spa_remove_pe_from_cache(link->platform_data, pe_handle); + WARN_ON(rc); + + mutex_unlock(&spa->spa_lock); + return rc; +} + int ocxl_link_remove_pe(void *link_handle, int pasid) { struct link *link = (struct link *) link_handle; diff --git a/drivers/misc/ocxl/ocxl_internal.h b/drivers/misc/ocxl/ocxl_internal.h index 5d421824afd9..a32f2151029f 100644 --- a/drivers/misc/ocxl/ocxl_internal.h +++ b/drivers/misc/ocxl/ocxl_internal.h @@ -77,6 +77,7 @@ struct ocxl_context { struct ocxl_xsl_error xsl_error; struct mutex irq_lock; struct idr irq_idr; + u16 tidr; // Thread ID used for P9 wait implementation }; struct ocxl_process_element { diff --git a/include/misc/ocxl.h b/include/misc/ocxl.h index 51ccf76db293..9ff6ddc28e22 100644 --- a/include/misc/ocxl.h +++ b/include/misc/ocxl.h @@ -188,6 +188,15 @@ extern 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); +/** + * Update values within a Process Element + * + * link_handle: the link handle associated with the process element + * 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); + /* * Remove a Process Element from the Shared Process Area for a link */ diff --git a/include/uapi/misc/ocxl.h b/include/uapi/misc/ocxl.h index 0af83d80fb3e..561e6f0dfcb7 100644 --- a/include/uapi/misc/ocxl.h +++ b/include/uapi/misc/ocxl.h @@ -48,6 +48,13 @@ struct ocxl_ioctl_metadata { __u64 reserved[13]; // Total of 16*u64 }; +struct ocxl_ioctl_p9_wait { + __u16 thread_id; // The thread ID required to wake this thread + __u16 reserved1; + __u32 reserved2; + __u64 reserved3[3]; +}; + struct ocxl_ioctl_irq_fd { __u64 irq_offset; __s32 eventfd; @@ -62,5 +69,6 @@ struct ocxl_ioctl_irq_fd { #define OCXL_IOCTL_IRQ_FREE _IOW(OCXL_MAGIC, 0x12, __u64) #define OCXL_IOCTL_IRQ_SET_FD _IOW(OCXL_MAGIC, 0x13, struct ocxl_ioctl_irq_fd) #define OCXL_IOCTL_GET_METADATA _IOR(OCXL_MAGIC, 0x14, struct ocxl_ioctl_metadata) +#define OCXL_IOCTL_ENABLE_P9_WAIT _IOR(OCXL_MAGIC, 0x15, struct ocxl_ioctl_p9_wait) #endif /* _UAPI_MISC_OCXL_H */ -- cgit v1.2.3 From 02a8e5bc1c06045f36423bd9632ad9f40da18d3f Mon Sep 17 00:00:00 2001 From: Alastair D'Silva Date: Fri, 11 May 2018 16:13:02 +1000 Subject: ocxl: Add an IOCTL so userspace knows what OCXL features are available In order for a userspace AFU driver to call the POWER9 specific OCXL_IOCTL_ENABLE_P9_WAIT, it needs to verify that it can actually make that call. Signed-off-by: Alastair D'Silva Acked-by: Frederic Barrat Acked-by: Andrew Donnellan Signed-off-by: Michael Ellerman --- drivers/misc/ocxl/file.c | 25 +++++++++++++++++++++++++ include/uapi/misc/ocxl.h | 6 ++++++ 2 files changed, 31 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c index eb409a469f21..33ae46ce0a8a 100644 --- a/drivers/misc/ocxl/file.c +++ b/drivers/misc/ocxl/file.c @@ -168,12 +168,32 @@ static long afu_ioctl_enable_p9_wait(struct ocxl_context *ctx, } #endif + +static long afu_ioctl_get_features(struct ocxl_context *ctx, + struct ocxl_ioctl_features __user *uarg) +{ + struct ocxl_ioctl_features arg; + + memset(&arg, 0, sizeof(arg)); + +#ifdef CONFIG_PPC64 + if (cpu_has_feature(CPU_FTR_P9_TIDR)) + arg.flags[0] |= OCXL_IOCTL_FEATURES_FLAGS0_P9_WAIT; +#endif + + if (copy_to_user(uarg, &arg, sizeof(arg))) + return -EFAULT; + + return 0; +} + #define CMD_STR(x) (x == OCXL_IOCTL_ATTACH ? "ATTACH" : \ x == OCXL_IOCTL_IRQ_ALLOC ? "IRQ_ALLOC" : \ x == OCXL_IOCTL_IRQ_FREE ? "IRQ_FREE" : \ x == OCXL_IOCTL_IRQ_SET_FD ? "IRQ_SET_FD" : \ x == OCXL_IOCTL_GET_METADATA ? "GET_METADATA" : \ x == OCXL_IOCTL_ENABLE_P9_WAIT ? "ENABLE_P9_WAIT" : \ + x == OCXL_IOCTL_GET_FEATURES ? "GET_FEATURES" : \ "UNKNOWN") static long afu_ioctl(struct file *file, unsigned int cmd, @@ -239,6 +259,11 @@ static long afu_ioctl(struct file *file, unsigned int cmd, break; #endif + case OCXL_IOCTL_GET_FEATURES: + rc = afu_ioctl_get_features(ctx, + (struct ocxl_ioctl_features __user *) args); + break; + default: rc = -EINVAL; } diff --git a/include/uapi/misc/ocxl.h b/include/uapi/misc/ocxl.h index 561e6f0dfcb7..97937cfa3baa 100644 --- a/include/uapi/misc/ocxl.h +++ b/include/uapi/misc/ocxl.h @@ -55,6 +55,11 @@ struct ocxl_ioctl_p9_wait { __u64 reserved3[3]; }; +#define OCXL_IOCTL_FEATURES_FLAGS0_P9_WAIT 0x01 +struct ocxl_ioctl_features { + __u64 flags[4]; +}; + struct ocxl_ioctl_irq_fd { __u64 irq_offset; __s32 eventfd; @@ -70,5 +75,6 @@ struct ocxl_ioctl_irq_fd { #define OCXL_IOCTL_IRQ_SET_FD _IOW(OCXL_MAGIC, 0x13, struct ocxl_ioctl_irq_fd) #define OCXL_IOCTL_GET_METADATA _IOR(OCXL_MAGIC, 0x14, struct ocxl_ioctl_metadata) #define OCXL_IOCTL_ENABLE_P9_WAIT _IOR(OCXL_MAGIC, 0x15, struct ocxl_ioctl_p9_wait) +#define OCXL_IOCTL_GET_FEATURES _IOR(OCXL_MAGIC, 0x16, struct ocxl_ioctl_features) #endif /* _UAPI_MISC_OCXL_H */ -- cgit v1.2.3 From 447808bf500a7cc92173266a59f8a494e132b122 Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Thu, 29 Mar 2018 17:02:46 +1100 Subject: hvc_opal: don't set tb_ticks_per_usec in udbg_init_opal_common() time_init() will set up tb_ticks_per_usec based on reality. time_init() is called *after* udbg_init_opal_common() during boot. from arch/powerpc/kernel/time.c: unsigned long tb_ticks_per_usec = 100; /* sane default */ Currently, all powernv systems have a timebase frequency of 512mhz (512000000/1000000 == 0x200) - although there's nothing written down anywhere that I can find saying that we couldn't make that different based on the requirements in the ISA. So, we've been (accidentally) thwacking the (currently) correct (for powernv at least) value for tb_ticks_per_usec earlier than we otherwise would have. The "sane default" seems to be adequate for our purposes between udbg_init_opal_common() and time_init() being called, and if it isn't, then we should probably be setting it somewhere that isn't hvc_opal.c! Signed-off-by: Stewart Smith Signed-off-by: Michael Ellerman --- drivers/tty/hvc/hvc_opal.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c index 2ed07ca6389e..9645c0062a90 100644 --- a/drivers/tty/hvc/hvc_opal.c +++ b/drivers/tty/hvc/hvc_opal.c @@ -318,7 +318,6 @@ static void udbg_init_opal_common(void) udbg_putc = udbg_opal_putc; udbg_getc = udbg_opal_getc; udbg_getc_poll = udbg_opal_getc_poll; - tb_ticks_per_usec = 0x200; /* Make udelay not suck */ } void __init hvc_opal_init_early(void) -- cgit v1.2.3 From 2e5c93d6bb2f7bc17eb82748943a1b9f6b068520 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 5 Jun 2018 09:16:21 +0000 Subject: ocxl: Fix missing unlock on error in afu_ioctl_enable_p9_wait() Add the missing unlock before return from function afu_ioctl_enable_p9_wait() in the error handling case. Fixes: e948e06fc63a ("ocxl: Expose the thread_id needed for wait on POWER9") Signed-off-by: Wei Yongjun Reviewed-by: Alastair D'Silva Signed-off-by: Michael Ellerman --- drivers/misc/ocxl/file.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c index 33ae46ce0a8a..e6a607488f8a 100644 --- a/drivers/misc/ocxl/file.c +++ b/drivers/misc/ocxl/file.c @@ -139,8 +139,10 @@ static long afu_ioctl_enable_p9_wait(struct ocxl_context *ctx, // Locks both status & tidr mutex_lock(&ctx->status_mutex); if (!ctx->tidr) { - if (set_thread_tidr(current)) + if (set_thread_tidr(current)) { + mutex_unlock(&ctx->status_mutex); return -ENOENT; + } ctx->tidr = current->thread.tidr; } -- cgit v1.2.3 From 0a4ec6aa035a52c422eceb2ed51ed88392a3d6c2 Mon Sep 17 00:00:00 2001 From: "Gautham R. Shenoy" Date: Thu, 31 May 2018 17:45:09 +0530 Subject: cpuidle: powernv: Fix promotion from snooze if next state disabled The commit 78eaa10f027c ("cpuidle: powernv/pseries: Auto-promotion of snooze to deeper idle state") introduced a timeout for the snooze idle state so that it could be eventually be promoted to a deeper idle state. The snooze timeout value is static and set to the target residency of the next idle state, which would train the cpuidle governor to pick the next idle state eventually. The unfortunate side-effect of this is that if the next idle state(s) is disabled, the CPU will forever remain in snooze, despite the fact that the system is completely idle, and other deeper idle states are available. This patch fixes the issue by dynamically setting the snooze timeout to the target residency of the next enabled state on the device. Before Patch: POWER8 : Only nap disabled. $ cpupower monitor sleep 30 sleep took 30.01297 seconds and exited with status 0 |Idle_Stats PKG |CORE|CPU | snoo | Nap | Fast 0| 8| 0| 96.41| 0.00| 0.00 0| 8| 1| 96.43| 0.00| 0.00 0| 8| 2| 96.47| 0.00| 0.00 0| 8| 3| 96.35| 0.00| 0.00 0| 8| 4| 96.37| 0.00| 0.00 0| 8| 5| 96.37| 0.00| 0.00 0| 8| 6| 96.47| 0.00| 0.00 0| 8| 7| 96.47| 0.00| 0.00 POWER9: Shallow states (stop0lite, stop1lite, stop2lite, stop0, stop1, stop2) disabled: $ cpupower monitor sleep 30 sleep took 30.05033 seconds and exited with status 0 |Idle_Stats PKG |CORE|CPU | snoo | stop | stop | stop | stop | stop | stop | stop | stop 0| 16| 0| 89.79| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00 0| 16| 1| 90.12| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00 0| 16| 2| 90.21| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00 0| 16| 3| 90.29| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00 After Patch: POWER8 : Only nap disabled. $ cpupower monitor sleep 30 sleep took 30.01200 seconds and exited with status 0 |Idle_Stats PKG |CORE|CPU | snoo | Nap | Fast 0| 8| 0| 16.58| 0.00| 77.21 0| 8| 1| 18.42| 0.00| 75.38 0| 8| 2| 4.70| 0.00| 94.09 0| 8| 3| 17.06| 0.00| 81.73 0| 8| 4| 3.06| 0.00| 95.73 0| 8| 5| 7.00| 0.00| 96.80 0| 8| 6| 1.00| 0.00| 98.79 0| 8| 7| 5.62| 0.00| 94.17 POWER9: Shallow states (stop0lite, stop1lite, stop2lite, stop0, stop1, stop2) disabled: $ cpupower monitor sleep 30 sleep took 30.02110 seconds and exited with status 0 |Idle_Stats PKG |CORE|CPU | snoo | stop | stop | stop | stop | stop | stop | stop | stop 0| 0| 0| 0.69| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 9.39| 89.70 0| 0| 1| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.05| 93.21 0| 0| 2| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 89.93 0| 0| 3| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 93.26 Fixes: 78eaa10f027c ("cpuidle: powernv/pseries: Auto-promotion of snooze to deeper idle state") Cc: stable@vger.kernel.org # v4.2+ Signed-off-by: Gautham R. Shenoy Reviewed-by: Balbir Singh Signed-off-by: Michael Ellerman --- drivers/cpuidle/cpuidle-powernv.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c index 1a8234e706bc..d29e4f041efe 100644 --- a/drivers/cpuidle/cpuidle-powernv.c +++ b/drivers/cpuidle/cpuidle-powernv.c @@ -43,9 +43,31 @@ struct stop_psscr_table { static struct stop_psscr_table stop_psscr_table[CPUIDLE_STATE_MAX] __read_mostly; -static u64 snooze_timeout __read_mostly; +static u64 default_snooze_timeout __read_mostly; static bool snooze_timeout_en __read_mostly; +static u64 get_snooze_timeout(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + int i; + + if (unlikely(!snooze_timeout_en)) + return default_snooze_timeout; + + for (i = index + 1; i < drv->state_count; i++) { + struct cpuidle_state *s = &drv->states[i]; + struct cpuidle_state_usage *su = &dev->states_usage[i]; + + if (s->disabled || su->disable) + continue; + + return s->target_residency * tb_ticks_per_usec; + } + + return default_snooze_timeout; +} + static int snooze_loop(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) @@ -56,7 +78,7 @@ static int snooze_loop(struct cpuidle_device *dev, local_irq_enable(); - snooze_exit_time = get_tb() + snooze_timeout; + snooze_exit_time = get_tb() + get_snooze_timeout(dev, drv, index); ppc64_runlatch_off(); HMT_very_low(); while (!need_resched()) { @@ -465,11 +487,9 @@ static int powernv_idle_probe(void) cpuidle_state_table = powernv_states; /* Device tree can indicate more idle states */ max_idle_state = powernv_add_idle_states(); - if (max_idle_state > 1) { + default_snooze_timeout = TICK_USEC * tb_ticks_per_usec; + if (max_idle_state > 1) snooze_timeout_en = true; - snooze_timeout = powernv_states[1].target_residency * - tb_ticks_per_usec; - } } else return -ENODEV; -- cgit v1.2.3