* Re: [PATCH v2 1/2] powerpc/set_memory: Avoid spinlock recursion in change_page_attr()
From: Michael Ellerman @ 2021-12-23 12:09 UTC (permalink / raw)
To: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras
Cc: Maxime Bizon, linuxppc-dev@lists.ozlabs.org,
linux-kernel@vger.kernel.org
In-Reply-To: <112b55c5fe019fefc284e3361772b00345fa0967.1639676816.git.christophe.leroy@csgroup.eu>
Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> Commit 1f9ad21c3b38 ("powerpc/mm: Implement set_memory() routines")
> included a spin_lock() to change_page_attr() in order to
> safely perform the three step operations. But then
> commit 9f7853d7609d ("powerpc/mm: Fix set_memory_*() against
> concurrent accesses") modify it to use pte_update() and do
> the operation atomically.
It's not really atomic, it's just safe against concurrent access.
We still do a read / modify / write of the pte value.
Which isn't safe against concurrent calls to change_page_attr() for the
same address.
But maybe that's OK? AFAICS other architectures (eg. arm64) have no
protection against concurrent callers. I think the assumption is higher
level code is ensuring there's only a single caller at a time.
On the other hand x86 and s390 do have locking (cpa_lock / cpa_mutex).
But it seems that's mostly to protect against splitting of page tables,
which we aren't doing.
We'd be a bit safer if we used pte_update() "properly", like I did in:
https://lore.kernel.org/linuxppc-dev/20210817132552.3375738-1-mpe@ellerman.id.au/
cheers
> In the meantime, Maxime reported some spinlock recursion.
>
> [ 15.351649] BUG: spinlock recursion on CPU#0, kworker/0:2/217
> [ 15.357540] lock: init_mm+0x3c/0x420, .magic: dead4ead, .owner: kworker/0:2/217, .owner_cpu: 0
> [ 15.366563] CPU: 0 PID: 217 Comm: kworker/0:2 Not tainted 5.15.0+ #523
> [ 15.373350] Workqueue: events do_free_init
> [ 15.377615] Call Trace:
> [ 15.380232] [e4105ac0] [800946a4] do_raw_spin_lock+0xf8/0x120 (unreliable)
> [ 15.387340] [e4105ae0] [8001f4ec] change_page_attr+0x40/0x1d4
> [ 15.393413] [e4105b10] [801424e0] __apply_to_page_range+0x164/0x310
> [ 15.400009] [e4105b60] [80169620] free_pcp_prepare+0x1e4/0x4a0
> [ 15.406045] [e4105ba0] [8016c5a0] free_unref_page+0x40/0x2b8
> [ 15.411979] [e4105be0] [8018724c] kasan_depopulate_vmalloc_pte+0x6c/0x94
> [ 15.418989] [e4105c00] [801424e0] __apply_to_page_range+0x164/0x310
> [ 15.425451] [e4105c50] [80187834] kasan_release_vmalloc+0xbc/0x134
> [ 15.431898] [e4105c70] [8015f7a8] __purge_vmap_area_lazy+0x4e4/0xdd8
> [ 15.438560] [e4105d30] [80160d10] _vm_unmap_aliases.part.0+0x17c/0x24c
> [ 15.445283] [e4105d60] [801642d0] __vunmap+0x2f0/0x5c8
> [ 15.450684] [e4105db0] [800e32d0] do_free_init+0x68/0x94
> [ 15.456181] [e4105dd0] [8005d094] process_one_work+0x4bc/0x7b8
> [ 15.462283] [e4105e90] [8005d614] worker_thread+0x284/0x6e8
> [ 15.468227] [e4105f00] [8006aaec] kthread+0x1f0/0x210
> [ 15.473489] [e4105f40] [80017148] ret_from_kernel_thread+0x14/0x1c
>
> Remove the spin_lock() in change_page_attr().
>
> Reported-by: Maxime Bizon <mbizon@freebox.fr>
> Link: https://lore.kernel.org/all/20211212112152.GA27070@sakura/
> Cc: Russell Currey <ruscur@russell.cc>
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
> arch/powerpc/mm/pageattr.c | 4 ----
> 1 file changed, 4 deletions(-)
>
> diff --git a/arch/powerpc/mm/pageattr.c b/arch/powerpc/mm/pageattr.c
> index edea388e9d3f..308adc51da9d 100644
> --- a/arch/powerpc/mm/pageattr.c
> +++ b/arch/powerpc/mm/pageattr.c
> @@ -30,8 +30,6 @@ static int change_page_attr(pte_t *ptep, unsigned long addr, void *data)
> long action = (long)data;
> pte_t pte;
>
> - spin_lock(&init_mm.page_table_lock);
> -
> pte = ptep_get(ptep);
>
> /* modify the PTE bits as desired, then apply */
> @@ -61,8 +59,6 @@ static int change_page_attr(pte_t *ptep, unsigned long addr, void *data)
>
> flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
>
> - spin_unlock(&init_mm.page_table_lock);
> -
> return 0;
> }
>
> --
> 2.33.1
^ permalink raw reply
* Re: [PATCH v2 00/20] powerpc: Define eligible functions as __init
From: Michael Ellerman @ 2021-12-23 11:44 UTC (permalink / raw)
To: Christophe Leroy, Nick Child, linuxppc-dev@lists.ozlabs.org
Cc: Nick Child, dja@axtens.net
In-Reply-To: <f1bdd55e-1141-c118-0f6d-b5ce61c6f7dd@csgroup.eu>
Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> Le 16/12/2021 à 23:00, Nick Child a écrit :
>>
>> Changes in v2:
>> - add `__init` in prototypes right before the funtion name instead of
>> at the end.
>> - respond to ./scripts/checkpatch feedback
>
> You probably missed the following comment from checkpatch:
>
> WARNING: From:/Signed-off-by: email address mismatch: 'From: Nick Child
> <nnac123@gmail.com>' != 'Signed-off-by: Nick Child <nick.child@ibm.com>'
I fixed it up when applying to use Nick's IBM address as the author.
> Sending from a different address is possible, but you then must add
>
> From: Nick Child <nick.child@ibm.com>
>
> at the top of the commit message.
>
> 'git format-patch' should be able to do it for you with the good option.
Yeah, Nick please teach git format-patch/send-email to use the right
address for future series. If you need any help just let me know.
cheers
^ permalink raw reply
* code conditional on non-existing PPC_EARLY_DEBUG_MICROWATT.
From: Lukas Bulwahn @ 2021-12-23 10:21 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
linuxppc-dev
Cc: kernel-janitors, Linux Kernel Mailing List
Dear Benjamin, dear Paul, dear Michael,
with commit 48b545b8018d ("powerpc/microwatt: Use standard 16550 UART
for console"), you have some code in arch/powerpc/kernel/udbg_16550.c,
conditional on the Kconfig symbol PPC_EARLY_DEBUG_MICROWATT. However,
since then, the definition of this Kconfig symbol was never introduced
to the mainline repository or current linux-next, nor am I finding any
pending patch for that.
Are you going to add this config definition soon? Or did you identify
that this setup code in udbg_16550.c is not actually needed and can we
simply drop this code again?
This issue was identified with the script ./scripts/checkkconfigsymbols.py.
Best regards,
Lukas
^ permalink raw reply
* [PATCH] Revert "mm/usercopy: Drop extra is_vmalloc_or_module() check"
From: Kefeng Wang @ 2021-12-23 10:21 UTC (permalink / raw)
To: Kees Cook, Laura Abbott, Mark Rutland, linux-mm, Andrew Morton,
linux-kernel, Michael Ellerman, Benjamin Herrenschmidt,
Paul Mackerras, linuxppc-dev
Cc: Kefeng Wang
This reverts commit 517e1fbeb65f5eade8d14f46ac365db6c75aea9b.
usercopy: Kernel memory exposure attempt detected from SLUB object not in SLUB page?! (offset 0, size 1048)!
kernel BUG at mm/usercopy.c:99
...
usercopy_abort+0x64/0xa0 (unreliable)
__check_heap_object+0x168/0x190
__check_object_size+0x1a0/0x200
dev_ethtool+0x2494/0x2b20
dev_ioctl+0x5d0/0x770
sock_do_ioctl+0xf0/0x1d0
sock_ioctl+0x3ec/0x5a0
__se_sys_ioctl+0xf0/0x160
system_call_exception+0xfc/0x1f0
system_call_common+0xf8/0x200
When run ethtool eth0, the BUG occurred, the code shows below,
data = vzalloc(array_size(gstrings.len, ETH_GSTRING_LEN));
copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN))
The data is alloced by vmalloc(), virt_addr_valid(ptr) will return true
on PowerPC64, which leads to the panic, add back the is_vmalloc_or_module()
check to fix it.
Fixes: 517e1fbeb65f (mm/usercopy: Drop extra is_vmalloc_or_module() check)
Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
mm/usercopy.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/mm/usercopy.c b/mm/usercopy.c
index b3de3c4eefba..cfc845403017 100644
--- a/mm/usercopy.c
+++ b/mm/usercopy.c
@@ -225,6 +225,17 @@ static inline void check_heap_object(const void *ptr, unsigned long n,
{
struct page *page;
+ /*
+ * Some architectures (PowerPC64) return true for virt_addr_valid() on
+ * vmalloced addresses. Work around this by checking for vmalloc
+ * first.
+ *
+ * We also need to check for module addresses explicitly since we
+ * may copy static data from modules to userspace
+ */
+ if (is_vmalloc_or_module_addr(ptr))
+ return;
+
if (!virt_addr_valid(ptr))
return;
--
2.26.2
^ permalink raw reply related
* Re: [PATCH/RFC] mm: add and use batched version of __tlb_remove_table()
From: Nikita Yushchenko @ 2021-12-23 9:55 UTC (permalink / raw)
To: Dave Hansen, Will Deacon, Aneesh Kumar K.V, Andrew Morton,
Nick Piggin, Peter Zijlstra, Catalin Marinas, Heiko Carstens,
Vasily Gorbik, Christian Borntraeger, David S. Miller,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen,
Arnd Bergmann
Cc: linux-arch, linux-s390, x86, linux-kernel, linux-mm, kernel,
sparclinux, linuxppc-dev
In-Reply-To: <290cfe1c-564f-9779-0757-5ca281055e77@intel.com>
[-- Attachment #1: Type: text/plain, Size: 1217 bytes --]
>> I currently don't have numbers for this patch taken alone. This patch
>> originates from work done some years ago to reduce cost of memory
>> accounting, and x86-only version of this patch was in virtuozzo/openvz
>> kernel since then. Other patches from that work have been upstreamed,
>> but this one was missed.
>>
>> Still it's obvious that release_pages() shall be faster that a loop
>> calling put_page() - isn't that exactly the reason why release_pages()
>> exists and is different from a loop calling put_page()?
>
> Yep, but this patch does a bunch of stuff to some really hot paths. It
> would be greatly appreciated if you could put in the effort to actually
> put some numbers behind this. Plenty of weird stuff happens on
> computers that we suck at predicting.
I found the original report about high cost of memory accounting, and tried to repeat the test described
there, with and without the patch.
The test is - run a script in 30 openvz containers in parallel, and measure average time per execution.
Script is attached.
I'm getting measurable improvement in average msecs per execution: 15360 ms without patch, 15170 ms with
patch. And this difference is reliably reproducible.
Nikita
[-- Attachment #2: calcprimes.sh --]
[-- Type: application/x-sh, Size: 468 bytes --]
^ permalink raw reply
* Re: [PATCH 1/5] crypto: sha256 - remove duplicate generic hash init function
From: Tianjia Zhang @ 2021-12-23 2:59 UTC (permalink / raw)
To: Julian Calaby
Cc: linux-s390, Thomas Bogendoerfer, Herbert Xu, Vasily Gorbik,
Heiko Carstens, linux-mips, LKML, Paul Mackerras, linux-crypto,
sparclinux, Alexander Gordeev, Christian Borntraeger,
linuxppc-dev, David S. Miller
In-Reply-To: <CAGRGNgXE_5H20K+e9oejqybOGh8JezMpi2yrDJKqaZ4rWJkZdA@mail.gmail.com>
Hi Julian,
On 12/23/21 6:35 AM, Julian Calaby wrote:
> Hi Tianjia,
>
> On Mon, Dec 20, 2021 at 8:25 PM Tianjia Zhang
> <tianjia.zhang@linux.alibaba.com> wrote:
>>
>> crypto_sha256_init() and sha256_base_init() are the same repeated
>> implementations, remove the crypto_sha256_init() in generic
>> implementation, sha224 is the same process.
>>
>> Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
>> ---
>> crypto/sha256_generic.c | 16 ++--------------
>> 1 file changed, 2 insertions(+), 14 deletions(-)
>>
>> diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c
>> index 3b377197236e..bf147b01e313 100644
>> --- a/crypto/sha256_generic.c
>> +++ b/crypto/sha256_generic.c
>> @@ -72,7 +60,7 @@ EXPORT_SYMBOL(crypto_sha256_finup);
>>
>> static struct shash_alg sha256_algs[2] = { {
>> .digestsize = SHA256_DIGEST_SIZE,
>> - .init = crypto_sha256_init,
>> + .init = sha256_base_init,
>> .update = crypto_sha256_update,
>> .final = crypto_sha256_final,
>> .finup = crypto_sha256_finup,
>> @@ -86,7 +74,7 @@ static struct shash_alg sha256_algs[2] = { {
>> }
>> }, {
>> .digestsize = SHA224_DIGEST_SIZE,
>> - .init = crypto_sha224_init,
>> + .init = sha224_base_init,
>> .update = crypto_sha256_update,
>> .final = crypto_sha256_final,
>> .finup = crypto_sha256_finup,
>
> Aren't these two functions defined as static inline functions? It
> appears that these crypto_ wrappers were added so there's "actual"
> referenceable functions for these structs.
>
> Did this actually compile?
>
> Thanks,
>
Judging from the compilation results, there is really no difference, but
the modification made by this patch is still necessary, because
crypto_sha256_init() wrapper and sha256_base_init() are two completely
duplicate functions.
Best regards,
Tianjia
^ permalink raw reply
* [PATCH] powerpc: fix spelling of "its"
From: Randy Dunlap @ 2021-12-23 0:39 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Randy Dunlap
Use the possessive "its" instead of the contraction of "it is" (it's).
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
---
arch/powerpc/perf/hv-24x7.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- linux-next-20211222.orig/arch/powerpc/perf/hv-24x7.c
+++ linux-next-20211222/arch/powerpc/perf/hv-24x7.c
@@ -756,7 +756,7 @@ static ssize_t catalog_event_len_validat
}
if (calc_ev_end > ev_end) {
- pr_warn("event %zu exceeds it's own length: event=%pK, end=%pK, offset=%zu, calc_ev_end=%pK\n",
+ pr_warn("event %zu exceeds its own length: event=%pK, end=%pK, offset=%zu, calc_ev_end=%pK\n",
event_idx, event, ev_end, offset, calc_ev_end);
return -1;
}
^ permalink raw reply
* [PATCH v2 10/10] powerpc/pseries/vas: Write 'target_creds' for QoS credits change
From: Haren Myneni @ 2021-12-23 0:32 UTC (permalink / raw)
To: mpe, linuxppc-dev, npiggin
In-Reply-To: <9d1730d5e0daf39ef17196b4699294dc2ccf4a63.camel@linux.ibm.com>
PowerVM support two types of credits - Default (uses normal priority
FIFO) and Qality of service (QoS uses high priproty FIFO). The user
decides the number of QoS credits and sets this value with HMC
interface. With the core add/removal, this value can be changed in HMC
which invokes drmgr to communicate to the kernel.
This patch adds an interface so that drmgr command can write the new
target QoS credits in sysfs. But the kernel gets the new QoS
capabilities from the hypervisor whenever target_creds is updated
to make sure sync with the values in the hypervisor.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
arch/powerpc/platforms/pseries/vas-sysfs.c | 34 +++++++++++++++++++++-
arch/powerpc/platforms/pseries/vas.c | 2 +-
arch/powerpc/platforms/pseries/vas.h | 1 +
3 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/vas-sysfs.c b/arch/powerpc/platforms/pseries/vas-sysfs.c
index f7609cdef8f8..66f1a0224811 100644
--- a/arch/powerpc/platforms/pseries/vas-sysfs.c
+++ b/arch/powerpc/platforms/pseries/vas-sysfs.c
@@ -36,6 +36,34 @@ static ssize_t avail_creds_show(struct vas_cop_feat_caps *caps, char *buf)
return sprintf(buf, "%d\n", avail_creds);
}
+/*
+ * This function is used to get the notification from the drmgr when
+ * QoS credits are changed as part of DLPAR core add/removal. Though
+ * receiving the total QoS credits here, get the official QoS
+ * capabilities from the hypervisor.
+ */
+static ssize_t target_creds_store(struct vas_cop_feat_caps *caps,
+ const char *buf, size_t count)
+{
+ int err;
+ u16 creds;
+
+ /*
+ * Nothing to do for default credit type.
+ */
+ if (caps->win_type == VAS_GZIP_DEF_FEAT_TYPE)
+ return -EOPNOTSUPP;
+
+ err = kstrtou16(buf, 0, &creds);
+ if (!err)
+ err = vas_reconfig_capabilties(caps->win_type);
+
+ if (err)
+ return -EINVAL;
+
+ return count;
+}
+
#define sysfs_capbs_entry_read(_name) \
static ssize_t _name##_show(struct vas_cop_feat_caps *caps, char *buf) \
{ \
@@ -52,8 +80,12 @@ struct vas_sysfs_entry {
sysfs_capbs_entry_read(_name); \
static struct vas_sysfs_entry _name##_attribute = __ATTR(_name, \
0444, _name##_show, NULL);
+#define VAS_ATTR(_name) \
+ sysfs_capbs_entry_read(_name); \
+ static struct vas_sysfs_entry _name##_attribute = __ATTR(_name, \
+ 0644, _name##_show, _name##_store)
-VAS_ATTR_RO(target_creds);
+VAS_ATTR(target_creds);
VAS_ATTR_RO(used_creds);
static struct vas_sysfs_entry avail_creds_attribute =
diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c
index 4b4048209c7d..169f0cccb166 100644
--- a/arch/powerpc/platforms/pseries/vas.c
+++ b/arch/powerpc/platforms/pseries/vas.c
@@ -714,7 +714,7 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds)
* changes. Reconfig window configurations based on the credits
* availability from this new capabilities.
*/
-static int vas_reconfig_capabilties(u8 type)
+int vas_reconfig_capabilties(u8 type)
{
struct hv_vas_cop_feat_caps *hv_caps;
struct vas_cop_feat_caps *caps;
diff --git a/arch/powerpc/platforms/pseries/vas.h b/arch/powerpc/platforms/pseries/vas.h
index bc393bd74030..4cf1d0ef66a5 100644
--- a/arch/powerpc/platforms/pseries/vas.h
+++ b/arch/powerpc/platforms/pseries/vas.h
@@ -125,5 +125,6 @@ struct pseries_vas_window {
};
int sysfs_add_vas_caps(struct vas_cop_feat_caps *caps);
+int vas_reconfig_capabilties(u8 type);
int __init sysfs_pseries_vas_init(struct vas_all_caps *vas_caps);
#endif /* _VAS_H */
--
2.27.0
^ permalink raw reply related
* [PATCH v2 09/10] powerpc/pseries/vas: sysfs interface to export capabilities
From: Haren Myneni @ 2021-12-23 0:31 UTC (permalink / raw)
To: mpe, linuxppc-dev, npiggin
In-Reply-To: <9d1730d5e0daf39ef17196b4699294dc2ccf4a63.camel@linux.ibm.com>
The hypervisor provides the available VAS GZIP capabilities such
as default or QoS window type and the target available credits in
each type. This patch creates sysfs entries and exports the target,
used and the available credits for each feature.
This interface can be used by the user space to determine the credits
usage or to set the target credits in the case of QoS type (for DLPAR).
/sys/devices/vas/vas0/gzip/def_caps: (default GZIP capabilities)
avail_creds /* Available credits to use */
target_creds /* Total credits available. Can be
/* changed with DLPAR operation */
used_creds /* Used credits */
/sys/devices/vas/vas0/gzip/qos_caps (QoS GZIP capabilities)
avail_creds
target_creds
used_creds
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
arch/powerpc/platforms/pseries/Makefile | 2 +-
arch/powerpc/platforms/pseries/vas-sysfs.c | 218 +++++++++++++++++++++
arch/powerpc/platforms/pseries/vas.c | 6 +
arch/powerpc/platforms/pseries/vas.h | 6 +
4 files changed, 231 insertions(+), 1 deletion(-)
create mode 100644 arch/powerpc/platforms/pseries/vas-sysfs.c
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 41d8aee98da4..349f42c31b65 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -30,6 +30,6 @@ obj-$(CONFIG_PPC_SVM) += svm.o
obj-$(CONFIG_FA_DUMP) += rtas-fadump.o
obj-$(CONFIG_SUSPEND) += suspend.o
-obj-$(CONFIG_PPC_VAS) += vas.o
+obj-$(CONFIG_PPC_VAS) += vas.o vas-sysfs.o
obj-$(CONFIG_ARCH_HAS_CC_PLATFORM) += cc_platform.o
diff --git a/arch/powerpc/platforms/pseries/vas-sysfs.c b/arch/powerpc/platforms/pseries/vas-sysfs.c
new file mode 100644
index 000000000000..f7609cdef8f8
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/vas-sysfs.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2016-17 IBM Corp.
+ */
+
+#define pr_fmt(fmt) "vas: " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/kobject.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+
+#include "vas.h"
+
+#ifdef CONFIG_SYSFS
+static struct kobject *pseries_vas_kobj;
+static struct kobject *gzip_caps_kobj;
+
+struct vas_caps_entry {
+ struct kobject kobj;
+ struct vas_cop_feat_caps *caps;
+};
+
+#define to_caps_entry(entry) container_of(entry, struct vas_caps_entry, kobj)
+
+static ssize_t avail_creds_show(struct vas_cop_feat_caps *caps, char *buf)
+{
+ /*
+ * avail_creds may be -ve if used_creds is oversubscribed,
+ * can happen if target_creds is reduced with DLPAR core removal.
+ */
+ int avail_creds = atomic_read(&caps->target_creds) -
+ atomic_read(&caps->used_creds);
+ return sprintf(buf, "%d\n", avail_creds);
+}
+
+#define sysfs_capbs_entry_read(_name) \
+static ssize_t _name##_show(struct vas_cop_feat_caps *caps, char *buf) \
+{ \
+ return sprintf(buf, "%d\n", atomic_read(&caps->_name)); \
+}
+
+struct vas_sysfs_entry {
+ struct attribute attr;
+ ssize_t (*show)(struct vas_cop_feat_caps *, char *);
+ ssize_t (*store)(struct vas_cop_feat_caps *, const char *, size_t);
+};
+
+#define VAS_ATTR_RO(_name) \
+ sysfs_capbs_entry_read(_name); \
+ static struct vas_sysfs_entry _name##_attribute = __ATTR(_name, \
+ 0444, _name##_show, NULL);
+
+VAS_ATTR_RO(target_creds);
+VAS_ATTR_RO(used_creds);
+
+static struct vas_sysfs_entry avail_creds_attribute =
+ __ATTR(avail_creds, 0444, avail_creds_show, NULL);
+
+static struct attribute *vas_capab_attrs[] = {
+ &target_creds_attribute.attr,
+ &used_creds_attribute.attr,
+ &avail_creds_attribute.attr,
+ NULL,
+};
+
+static ssize_t vas_type_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
+{
+ struct vas_caps_entry *centry;
+ struct vas_cop_feat_caps *caps;
+ struct vas_sysfs_entry *entry;
+
+ centry = to_caps_entry(kobj);
+ caps = centry->caps;
+ entry = container_of(attr, struct vas_sysfs_entry, attr);
+
+ if (!entry->show)
+ return -EIO;
+
+ return entry->show(caps, buf);
+}
+
+static ssize_t vas_type_store(struct kobject *kobj, struct attribute *attr,
+ const char *buf, size_t count)
+{
+ struct vas_caps_entry *centry;
+ struct vas_cop_feat_caps *caps;
+ struct vas_sysfs_entry *entry;
+
+ centry = to_caps_entry(kobj);
+ caps = centry->caps;
+ entry = container_of(attr, struct vas_sysfs_entry, attr);
+ if (!entry->store)
+ return -EIO;
+
+ return entry->store(caps, buf, count);
+}
+
+static void vas_type_release(struct kobject *kobj)
+{
+ struct vas_caps_entry *centry = to_caps_entry(kobj);
+ kfree(centry);
+}
+
+static const struct sysfs_ops vas_sysfs_ops = {
+ .show = vas_type_show,
+ .store = vas_type_store,
+};
+
+static struct kobj_type vas_attr_type = {
+ .release = vas_type_release,
+ .sysfs_ops = &vas_sysfs_ops,
+ .default_attrs = vas_capab_attrs,
+};
+
+static char *vas_caps_kobj_name(struct vas_cop_feat_caps *caps,
+ struct kobject **kobj)
+{
+ if (caps->descriptor == VAS_GZIP_QOS_CAPABILITIES) {
+ *kobj = gzip_caps_kobj;
+ return "qos_caps";
+ } else if (caps->descriptor == VAS_GZIP_DEFAULT_CAPABILITIES) {
+ *kobj = gzip_caps_kobj;
+ return "def_caps";
+ } else
+ return "Unknown";
+}
+
+/*
+ * Add feature specific capability dir entry.
+ * Ex: VDefGzip or VQosGzip
+ */
+int sysfs_add_vas_caps(struct vas_cop_feat_caps *caps)
+{
+ struct vas_caps_entry *centry;
+ struct kobject *kobj = NULL;
+ int ret = 0;
+ char *name;
+
+ centry = kzalloc(sizeof(*centry), GFP_KERNEL);
+ if (!centry)
+ return -ENOMEM;
+
+ kobject_init(¢ry->kobj, &vas_attr_type);
+ centry->caps = caps;
+ name = vas_caps_kobj_name(caps, &kobj);
+
+ if (kobj) {
+ ret = kobject_add(¢ry->kobj, kobj, "%s", name);
+
+ if (ret) {
+ pr_err("VAS: sysfs kobject add / event failed %d\n",
+ ret);
+ kobject_put(¢ry->kobj);
+ }
+ }
+
+ return ret;
+}
+
+static struct miscdevice vas_miscdev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "vas",
+};
+
+/*
+ * Add VAS and VasCaps (overall capabilities) dir entries.
+ */
+int __init sysfs_pseries_vas_init(struct vas_all_caps *vas_caps)
+{
+ int ret;
+
+ ret = misc_register(&vas_miscdev);
+ if (ret < 0) {
+ pr_err("%s: register vas misc device failed\n", __func__);
+ return ret;
+ }
+
+ /*
+ * The hypervisor does not expose multiple VAS instances, but can
+ * see multiple VAS instances on PowerNV. So create 'vas0' directory
+ * on PowerVM.
+ */
+ pseries_vas_kobj = kobject_create_and_add("vas0",
+ &vas_miscdev.this_device->kobj);
+ if (!pseries_vas_kobj) {
+ pr_err("Failed to create VAS sysfs entry\n");
+ return -ENOMEM;
+ }
+
+ if ((vas_caps->feat_type & VAS_GZIP_QOS_FEAT_BIT) ||
+ (vas_caps->feat_type & VAS_GZIP_DEF_FEAT_BIT)) {
+ gzip_caps_kobj = kobject_create_and_add("gzip",
+ pseries_vas_kobj);
+ if (!gzip_caps_kobj) {
+ pr_err("Failed to create VAS GZIP capability entry\n");
+ kobject_put(pseries_vas_kobj);
+ return -ENOMEM;
+ }
+ }
+
+ return 0;
+}
+
+#else
+int sysfs_add_vas_caps(struct vas_cop_feat_caps *caps)
+{
+ return 0;
+}
+
+int __init sysfs_pseries_vas_init(struct vas_all_caps *vas_caps)
+{
+ return 0;
+}
+#endif
diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c
index c7dec3adc3af..4b4048209c7d 100644
--- a/arch/powerpc/platforms/pseries/vas.c
+++ b/arch/powerpc/platforms/pseries/vas.c
@@ -553,6 +553,10 @@ static int get_vas_capabilities(u8 feat, enum vas_cop_feat_type type,
}
}
+ rc = sysfs_add_vas_caps(caps);
+ if (rc)
+ return rc;
+
copypaste_feat = true;
return 0;
@@ -832,6 +836,8 @@ static int __init pseries_vas_init(void)
caps_all.descriptor = be64_to_cpu(hv_caps->descriptor);
caps_all.feat_type = be64_to_cpu(hv_caps->feat_type);
+ sysfs_pseries_vas_init(&caps_all);
+
hv_cop_caps = kmalloc(sizeof(*hv_cop_caps), GFP_KERNEL);
if (!hv_cop_caps) {
rc = -ENOMEM;
diff --git a/arch/powerpc/platforms/pseries/vas.h b/arch/powerpc/platforms/pseries/vas.h
index 8ce9b84693e8..bc393bd74030 100644
--- a/arch/powerpc/platforms/pseries/vas.h
+++ b/arch/powerpc/platforms/pseries/vas.h
@@ -24,6 +24,9 @@
#define VAS_COPY_PASTE_USER_MODE 0x00000001
#define VAS_COP_OP_USER_MODE 0x00000010
+#define VAS_GZIP_QOS_CAPABILITIES 0x56516F73477A6970
+#define VAS_GZIP_DEFAULT_CAPABILITIES 0x56446566477A6970
+
/*
* Co-processor feature - GZIP QoS windows or GZIP default windows
*/
@@ -120,4 +123,7 @@ struct pseries_vas_window {
char *name;
int fault_virq;
};
+
+int sysfs_add_vas_caps(struct vas_cop_feat_caps *caps);
+int __init sysfs_pseries_vas_init(struct vas_all_caps *vas_caps);
#endif /* _VAS_H */
--
2.27.0
^ permalink raw reply related
* [PATCH v2 08/10] powerpc/vas: Return paste instruction failure if no active window
From: Haren Myneni @ 2021-12-23 0:30 UTC (permalink / raw)
To: mpe, linuxppc-dev, npiggin
In-Reply-To: <9d1730d5e0daf39ef17196b4699294dc2ccf4a63.camel@linux.ibm.com>
The VAS window may not be active if the system looses credits and
the NX generates page fault when it receives request on unmap
paste address.
The kernel handles the fault by remap new paste address if the
window is active again, Otherwise return the paste instruction
failure if the executed instruction that caused the fault was
a paste.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
arch/powerpc/include/asm/ppc-opcode.h | 2 ++
arch/powerpc/platforms/book3s/vas-api.c | 47 ++++++++++++++++++++++++-
2 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/ppc-opcode.h
b/arch/powerpc/include/asm/ppc-opcode.h
index baea657bc868..30bb3c0e07f9 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -261,6 +261,8 @@
#define PPC_INST_MFSPR_PVR 0x7c1f42a6
#define PPC_INST_MFSPR_PVR_MASK 0xfc1ffffe
#define PPC_INST_MTMSRD 0x7c000164
+#define PPC_INST_PASTE 0x7c20070d
+#define PPC_INST_PASTE_MASK 0xfc2007ff
#define PPC_INST_POPCNTB 0x7c0000f4
#define PPC_INST_POPCNTB_MASK 0xfc0007fe
#define PPC_INST_RFEBB 0x4c000124
diff --git a/arch/powerpc/platforms/book3s/vas-api.c
b/arch/powerpc/platforms/book3s/vas-api.c
index 5ceba75c13eb..2ffd34bc4032 100644
--- a/arch/powerpc/platforms/book3s/vas-api.c
+++ b/arch/powerpc/platforms/book3s/vas-api.c
@@ -351,6 +351,41 @@ static int coproc_release(struct inode *inode,
struct file *fp)
return 0;
}
+/*
+ * If the executed instruction that caused the fault was a paste, then
+ * clear regs CR0[EQ], advance NIP, and return 0. Else return error
code.
+ */
+static int do_fail_paste(void)
+{
+ struct pt_regs *regs = current->thread.regs;
+ u32 instword;
+
+ if (WARN_ON_ONCE(!regs))
+ return -EINVAL;
+
+ if (WARN_ON_ONCE(!user_mode(regs)))
+ return -EINVAL;
+
+ /*
+ * If we couldn't translate the instruction, the driver should
+ * return success without handling the fault, it will be
retried
+ * or the instruction fetch will fault.
+ */
+ if (get_user(instword, (u32 __user *)(regs->nip)))
+ return -EAGAIN;
+
+ /*
+ * Not a paste instruction, driver may fail the fault.
+ */
+ if ((instword & PPC_INST_PASTE_MASK) != PPC_INST_PASTE)
+ return -ENOENT;
+
+ regs->ccr &= ~0xe0000000; /* Clear CR0[0-2] to fail paste
*/
+ regs_add_return_ip(regs, 4); /* Skip the paste */
+
+ return 0;
+}
+
/*
* This fault handler is invoked when the VAS/NX generates page fault
on
* the paste address. Happens if the kernel closes window in
hypervisor
@@ -403,9 +438,19 @@ static vm_fault_t vas_mmap_fault(struct vm_fault
*vmf)
}
mutex_unlock(&txwin->task_ref.mmap_mutex);
- return VM_FAULT_SIGBUS;
+ /*
+ * Received this fault due to closing the actual window.
+ * It can happen during migration or lost credits.
+ * Since no mapping, return the paste instruction failure
+ * to the user space.
+ */
+ ret = do_fail_paste();
+ if (!ret)
+ return VM_FAULT_NOPAGE;
+ return VM_FAULT_SIGBUS;
}
+
static const struct vm_operations_struct vas_vm_ops = {
.fault = vas_mmap_fault,
};
--
2.27.0
^ permalink raw reply related
* [PATCH v2 07/10] powerpc/vas: Add paste address mmap fault handler
From: Haren Myneni @ 2021-12-23 0:29 UTC (permalink / raw)
To: mpe, linuxppc-dev, npiggin
In-Reply-To: <9d1730d5e0daf39ef17196b4699294dc2ccf4a63.camel@linux.ibm.com>
The user space opens VAS windows and issues NX requests by pasting
CRB on the corresponding paste address mmap. When the system looses
credits due to core removal, the kernel has to close the window in
the hypervisor and make the window inactive by unmapping this paste
address. Also the OS has to handle NX request page faults if the user
space issue NX requests.
This handler remap the new paste address with the same VMA when the
window is active again (due to core add with DLPAR). Otherwise
returns paste failure.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
arch/powerpc/platforms/book3s/vas-api.c | 60 +++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/arch/powerpc/platforms/book3s/vas-api.c b/arch/powerpc/platforms/book3s/vas-api.c
index 2d06bd1b1935..5ceba75c13eb 100644
--- a/arch/powerpc/platforms/book3s/vas-api.c
+++ b/arch/powerpc/platforms/book3s/vas-api.c
@@ -351,6 +351,65 @@ static int coproc_release(struct inode *inode, struct file *fp)
return 0;
}
+/*
+ * This fault handler is invoked when the VAS/NX generates page fault on
+ * the paste address. Happens if the kernel closes window in hypervisor
+ * (on PowerVM) due to lost credit or the paste address is not mapped.
+ */
+static vm_fault_t vas_mmap_fault(struct vm_fault *vmf)
+{
+ struct vm_area_struct *vma = vmf->vma;
+ struct file *fp = vma->vm_file;
+ struct coproc_instance *cp_inst = fp->private_data;
+ struct vas_window *txwin;
+ u64 paste_addr;
+ int ret;
+
+ /*
+ * window is not opened. Shouldn't expect this error.
+ */
+ if (!cp_inst || !cp_inst->txwin) {
+ pr_err("%s(): No send window open?\n", __func__);
+ return VM_FAULT_SIGBUS;
+ }
+
+ txwin = cp_inst->txwin;
+ /*
+ * Fault is coming due to missing from the original mmap.
+ * Can happen only when the window is closed due to lost
+ * credit before mmap() or the user space issued NX request
+ * without mapping.
+ */
+ if (txwin->task_ref.vma != vmf->vma) {
+ pr_err("%s(): No previous mapping with paste address\n",
+ __func__);
+ return VM_FAULT_SIGBUS;
+ }
+
+ mutex_lock(&txwin->task_ref.mmap_mutex);
+ /*
+ * The window may be inactive due to lost credit (Ex: core
+ * removal with DLPAR). When the window is active again when
+ * the credit is available, remap with the new paste address.
+ */
+ if (txwin->status == VAS_WIN_ACTIVE) {
+ paste_addr = cp_inst->coproc->vops->paste_addr(txwin);
+ if (paste_addr) {
+ ret = vmf_insert_pfn(vma, vma->vm_start,
+ (paste_addr >> PAGE_SHIFT));
+ mutex_unlock(&txwin->task_ref.mmap_mutex);
+ return ret;
+ }
+ }
+ mutex_unlock(&txwin->task_ref.mmap_mutex);
+
+ return VM_FAULT_SIGBUS;
+
+}
+static const struct vm_operations_struct vas_vm_ops = {
+ .fault = vas_mmap_fault,
+};
+
static int coproc_mmap(struct file *fp, struct vm_area_struct *vma)
{
struct coproc_instance *cp_inst = fp->private_data;
@@ -417,6 +476,7 @@ static int coproc_mmap(struct file *fp, struct vm_area_struct *vma)
paste_addr, vma->vm_start, rc);
txwin->task_ref.vma = vma;
+ vma->vm_ops = &vas_vm_ops;
out:
mutex_unlock(&txwin->task_ref.mmap_mutex);
--
2.27.0
^ permalink raw reply related
* [PATCH v2 06/10] powerpc/vas: Map paste address only if window is active
From: Haren Myneni @ 2021-12-23 0:29 UTC (permalink / raw)
To: mpe, linuxppc-dev, npiggin
In-Reply-To: <9d1730d5e0daf39ef17196b4699294dc2ccf4a63.camel@linux.ibm.com>
The paste address mapping is done with mmap() after the window is
opened with ioctl. But the window can be closed due to lost credit
due to core removal before mmap(). So if the window is not active,
return mmap() failure with -EACCES and expects the user space reissue
mmap() when the window is active or open new window when the credit
is available.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
arch/powerpc/platforms/book3s/vas-api.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/book3s/vas-api.c b/arch/powerpc/platforms/book3s/vas-api.c
index a63fd48e34a7..2d06bd1b1935 100644
--- a/arch/powerpc/platforms/book3s/vas-api.c
+++ b/arch/powerpc/platforms/book3s/vas-api.c
@@ -379,10 +379,27 @@ static int coproc_mmap(struct file *fp, struct vm_area_struct *vma)
return -EACCES;
}
+ /*
+ * The initial mapping is done after the window is opened
+ * with ioctl. But this window might have been closed
+ * due to lost credit (core removal on PowerVM) before mmap().
+ * So if the window is not active, return mmap() failure
+ * with -EACCES and expects the user space reconfigure (mmap)
+ * window when it is active again or open new window when
+ * the credit is available.
+ */
+ mutex_lock(&txwin->task_ref.mmap_mutex);
+ if (txwin->status != VAS_WIN_ACTIVE) {
+ pr_err("%s(): Window is not active\n", __func__);
+ rc = -EACCES;
+ goto out;
+ }
+
paste_addr = cp_inst->coproc->vops->paste_addr(txwin);
if (!paste_addr) {
pr_err("%s(): Window paste address failed\n", __func__);
- return -EINVAL;
+ rc = -EINVAL;
+ goto out;
}
pfn = paste_addr >> PAGE_SHIFT;
@@ -401,6 +418,8 @@ static int coproc_mmap(struct file *fp, struct vm_area_struct *vma)
txwin->task_ref.vma = vma;
+out:
+ mutex_unlock(&txwin->task_ref.mmap_mutex);
return rc;
}
--
2.27.0
^ permalink raw reply related
* [PATCH v2 05/10] powerpc/pseries/vas: Close windows with DLPAR core removal
From: Haren Myneni @ 2021-12-23 0:28 UTC (permalink / raw)
To: mpe, linuxppc-dev, npiggin
In-Reply-To: <9d1730d5e0daf39ef17196b4699294dc2ccf4a63.camel@linux.ibm.com>
The hypervisor reduces the available credits if the core is removed
from the LPAR. So there is possibility of using excessive credits
(windows) in the LPAR and the hypervisor expects the system to close
the excessive windows. Even though the user space can continue to use
these windows to send compression requests to NX, the hypervisor expects
the LPAR to reduce these windows usage so that NX load can be equally
distributed across all LPARs in the system.
When the DLPAR notifier is received, get the new VAS capabilities from
the hypervisor and close the excessive windows in the hypervisor. Also
the kernel unmaps the paste address so that the user space receives paste
failure until these windows are active with the later DLPAR (core add).
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
arch/powerpc/include/asm/vas.h | 1 +
arch/powerpc/platforms/book3s/vas-api.c | 2 +
arch/powerpc/platforms/pseries/vas.c | 117 ++++++++++++++++++++++--
arch/powerpc/platforms/pseries/vas.h | 1 +
4 files changed, 112 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/include/asm/vas.h b/arch/powerpc/include/asm/vas.h
index 43cea69d1af1..72d1df038b4b 100644
--- a/arch/powerpc/include/asm/vas.h
+++ b/arch/powerpc/include/asm/vas.h
@@ -73,6 +73,7 @@ struct vas_user_win_ref {
struct mm_struct *mm; /* Linux process mm_struct */
struct mutex mmap_mutex; /* protects paste address mmap() */
/* with DLPAR close/open windows */
+ struct vm_area_struct *vma; /* Save VMA and used in DLPAR ops */
};
/*
diff --git a/arch/powerpc/platforms/book3s/vas-api.c b/arch/powerpc/platforms/book3s/vas-api.c
index 2b0ced611f32..a63fd48e34a7 100644
--- a/arch/powerpc/platforms/book3s/vas-api.c
+++ b/arch/powerpc/platforms/book3s/vas-api.c
@@ -399,6 +399,8 @@ static int coproc_mmap(struct file *fp, struct vm_area_struct *vma)
pr_devel("%s(): paste addr %llx at %lx, rc %d\n", __func__,
paste_addr, vma->vm_start, rc);
+ txwin->task_ref.vma = vma;
+
return rc;
}
diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c
index 0666d3630e6b..c7dec3adc3af 100644
--- a/arch/powerpc/platforms/pseries/vas.c
+++ b/arch/powerpc/platforms/pseries/vas.c
@@ -363,13 +363,28 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
if (rc)
goto out_free;
- vas_user_win_add_mm_context(&txwin->vas_win.task_ref);
txwin->win_type = cop_feat_caps->win_type;
mutex_lock(&vas_pseries_mutex);
- list_add(&txwin->win_list, &caps->list);
+ /*
+ * Possible to loose the acquired credit with DLPAR core
+ * removal after the window is opened. So if there are any
+ * closed windows (means with lost credits), do not give new
+ * window to user space. New windows will be opened only
+ * after the existing windows are reopened when credits are
+ * available.
+ */
+ if (!caps->close_wins) {
+ list_add(&txwin->win_list, &caps->list);
+ caps->num_wins++;
+ mutex_unlock(&vas_pseries_mutex);
+ vas_user_win_add_mm_context(&txwin->vas_win.task_ref);
+ return &txwin->vas_win;
+ }
mutex_unlock(&vas_pseries_mutex);
- return &txwin->vas_win;
+ put_vas_user_win_ref(&txwin->vas_win.task_ref);
+ rc = -EBUSY;
+ pr_err("No credit is available to allocate window\n");
out_free:
/*
@@ -432,14 +447,24 @@ static int vas_deallocate_window(struct vas_window *vwin)
caps = &vascaps[win->win_type].caps;
mutex_lock(&vas_pseries_mutex);
- rc = deallocate_free_window(win);
- if (rc) {
- mutex_unlock(&vas_pseries_mutex);
- return rc;
- }
+ /*
+ * VAS window is already closed in the hypervisor when
+ * lost the credit. So just remove the entry from
+ * the list, remove task references and free vas_window
+ * struct.
+ */
+ if (win->vas_win.status != VAS_WIN_NO_CRED_CLOSE) {
+ rc = deallocate_free_window(win);
+ if (rc) {
+ mutex_unlock(&vas_pseries_mutex);
+ return rc;
+ }
+ } else
+ vascaps[win->win_type].close_wins--;
list_del(&win->win_list);
atomic_dec(&caps->used_creds);
+ vascaps[win->win_type].num_wins--;
mutex_unlock(&vas_pseries_mutex);
put_vas_user_win_ref(&vwin->task_ref);
@@ -614,6 +639,72 @@ static int reconfig_open_windows(struct vas_caps *vcaps, int creds)
return rc;
}
+/*
+ * The hypervisor reduces the available credits if the LPAR lost core. It
+ * means the excessive windows should not be active and the user space
+ * should not be using these windows to send compression requests to NX.
+ * So the kernel closes the excessive windows and unmap the paste address
+ * such that the user space receives paste instruction failure. Then up to
+ * the user space to fall back to SW compression and manage with the
+ * existing windows.
+ */
+static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds)
+{
+ struct pseries_vas_window *win, *tmp;
+ struct vas_user_win_ref *task_ref;
+ struct vm_area_struct *vma;
+ int rc = 0;
+
+ list_for_each_entry_safe(win, tmp, &vcap->list, win_list) {
+ /*
+ * This window is already closed due to lost credit
+ * before. Go for next window.
+ */
+ if (win->vas_win.status == VAS_WIN_NO_CRED_CLOSE)
+ continue;
+
+ task_ref = &win->vas_win.task_ref;
+ mutex_lock(&task_ref->mmap_mutex);
+ vma = task_ref->vma;
+ /*
+ * Number of available credits are reduced, So select
+ * and close windows.
+ */
+ win->vas_win.status = VAS_WIN_NO_CRED_CLOSE;
+
+ mmap_write_lock(task_ref->mm);
+ /*
+ * vma is set in the original mapping. But this mapping
+ * is done with mmap() after the window is opened with ioctl.
+ * so we may not see the original mapping if the core remove
+ * is done before the original mmap() and after the ioctl.
+ */
+ if (vma)
+ zap_page_range(vma, vma->vm_start,
+ vma->vm_end - vma->vm_start);
+
+ mmap_write_unlock(task_ref->mm);
+ mutex_unlock(&task_ref->mmap_mutex);
+ /*
+ * Close VAS window in the hypervisor, but do not
+ * free vas_window struct since it may be reused
+ * when the credit is available later (DLPAR with
+ * adding cores). This struct will be used
+ * later when the process issued with close(FD).
+ */
+ rc = deallocate_free_window(win);
+ if (rc)
+ return rc;
+
+ vcap->close_wins++;
+
+ if (!--excess_creds)
+ break;
+ }
+
+ return 0;
+}
+
/*
* Get new VAS capabilities when the core add/removal configuration
* changes. Reconfig window configurations based on the credits
@@ -625,7 +716,7 @@ static int vas_reconfig_capabilties(u8 type)
struct vas_cop_feat_caps *caps;
int lpar_creds, new_creds;
struct vas_caps *vcaps;
- int rc = 0;
+ int rc = 0, active_wins;
if (type >= VAS_MAX_FEAT_TYPE) {
pr_err("Invalid credit type %d\n", type);
@@ -663,6 +754,14 @@ static int vas_reconfig_capabilties(u8 type)
* the previous DLPAR (core removal).
*/
rc = reconfig_open_windows(vcaps, new_creds - lpar_creds);
+ } else {
+ /*
+ * # active windows is more than new LPAR available
+ * credits. So close the excessive windows.
+ */
+ active_wins = vcaps->num_wins - vcaps->close_wins;
+ if (active_wins > new_creds)
+ rc = reconfig_close_windows(vcaps, active_wins - new_creds);
}
out:
diff --git a/arch/powerpc/platforms/pseries/vas.h b/arch/powerpc/platforms/pseries/vas.h
index 45b62565955b..8ce9b84693e8 100644
--- a/arch/powerpc/platforms/pseries/vas.h
+++ b/arch/powerpc/platforms/pseries/vas.h
@@ -79,6 +79,7 @@ struct vas_caps {
struct vas_cop_feat_caps caps;
struct list_head list; /* List of open windows */
int close_wins; /* closed windows in the hypervisor for DLPAR */
+ int num_wins; /* Number of windows opened */
u8 feat; /* Feature type */
};
--
2.27.0
^ permalink raw reply related
* [PATCH v2 04/10] powerpc/pseries/vas: Reopen windows with DLPAR core add
From: Haren Myneni @ 2021-12-23 0:27 UTC (permalink / raw)
To: mpe, linuxppc-dev, npiggin
In-Reply-To: <9d1730d5e0daf39ef17196b4699294dc2ccf4a63.camel@linux.ibm.com>
VAS windows can be closed in the hypervisor due to lost credits
when the core is removed. If these credits are available later
for core add, reopen these windows and set them active. When the
kernel sees page fault on the paste address, it creates new mapping
on the new paste address. Then the user space can continue to use
these windows and send HW compression requests to NX successfully.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
arch/powerpc/include/asm/vas.h | 15 +++
arch/powerpc/platforms/book3s/vas-api.c | 1 +
arch/powerpc/platforms/pseries/vas.c | 143 ++++++++++++++++++++++++
arch/powerpc/platforms/pseries/vas.h | 8 +-
4 files changed, 161 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/include/asm/vas.h b/arch/powerpc/include/asm/vas.h
index 57573d9c1e09..43cea69d1af1 100644
--- a/arch/powerpc/include/asm/vas.h
+++ b/arch/powerpc/include/asm/vas.h
@@ -29,6 +29,18 @@
#define VAS_THRESH_FIFO_GT_QTR_FULL 2
#define VAS_THRESH_FIFO_GT_EIGHTH_FULL 3
+/*
+ * VAS window status
+ */
+#define VAS_WIN_ACTIVE 0x0 /* Used in platform independent */
+ /* vas mmap() */
+#define VAS_WIN_CLOSED 0x1
+#define VAS_WIN_INACTIVE 0x2 /* Inactive due to HW failure */
+#define VAS_WIN_MOD_IN_PROCESS 0x3 /* Process of being modified, */
+ /* deallocated, or quiesced */
+#define VAS_WIN_NO_CRED_CLOSE 0x4 /* Linux specific status when */
+ /* window is closed due to lost */
+ /* credit */
/*
* Get/Set bit fields
*/
@@ -59,6 +71,8 @@ struct vas_user_win_ref {
struct pid *pid; /* PID of owner */
struct pid *tgid; /* Thread group ID of owner */
struct mm_struct *mm; /* Linux process mm_struct */
+ struct mutex mmap_mutex; /* protects paste address mmap() */
+ /* with DLPAR close/open windows */
};
/*
@@ -67,6 +81,7 @@ struct vas_user_win_ref {
struct vas_window {
u32 winid;
u32 wcreds_max; /* Window credits */
+ u32 status;
enum vas_cop_type cop;
struct vas_user_win_ref task_ref;
char *dbgname;
diff --git a/arch/powerpc/platforms/book3s/vas-api.c b/arch/powerpc/platforms/book3s/vas-api.c
index 4d82c92ddd52..2b0ced611f32 100644
--- a/arch/powerpc/platforms/book3s/vas-api.c
+++ b/arch/powerpc/platforms/book3s/vas-api.c
@@ -316,6 +316,7 @@ static int coproc_ioc_tx_win_open(struct file *fp, unsigned long arg)
return PTR_ERR(txwin);
}
+ mutex_init(&txwin->task_ref.mmap_mutex);
cp_inst->txwin = txwin;
return 0;
diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c
index fb6e6a6261a5..0666d3630e6b 100644
--- a/arch/powerpc/platforms/pseries/vas.c
+++ b/arch/powerpc/platforms/pseries/vas.c
@@ -494,6 +494,7 @@ static int get_vas_capabilities(u8 feat, enum vas_cop_feat_type type,
memset(vcaps, 0, sizeof(*vcaps));
INIT_LIST_HEAD(&vcaps->list);
+ vcaps->feat = feat;
caps = &vcaps->caps;
rc = h_query_vas_capabilities(H_QUERY_VAS_CAPABILITIES, feat,
@@ -532,6 +533,144 @@ static int get_vas_capabilities(u8 feat, enum vas_cop_feat_type type,
return 0;
}
+/*
+ * VAS windows can be closed due to lost credits when the core is
+ * removed. So reopen them if credits are available due to DLPAR
+ * core add and set the window active status. When NX sees the page
+ * fault on the unmapped paste address, the kernel handles the fault
+ * by setting the remapping to new paste address if the window is
+ * active.
+ */
+static int reconfig_open_windows(struct vas_caps *vcaps, int creds)
+{
+ long domain[PLPAR_HCALL9_BUFSIZE] = {VAS_DEFAULT_DOMAIN_ID};
+ struct vas_cop_feat_caps *caps = &vcaps->caps;
+ struct pseries_vas_window *win = NULL, *tmp;
+ int rc, mv_ents = 0;
+
+ /*
+ * Nothing to do if there are no closed windows.
+ */
+ if (!vcaps->close_wins)
+ return 0;
+
+ /*
+ * For the core removal, the hypervisor reduces the credits
+ * assigned to the LPAR and the kernel closes VAS windows
+ * in the hypervisor depends on reduced credits. The kernel
+ * uses LIFO (the last windows that are opened will be closed
+ * first) and expects to open in the same order when credits
+ * are available.
+ * For example, 40 windows are closed when the LPAR lost 2 cores
+ * (dedicated). If 1 core is added, this LPAR can have 20 more
+ * credits. It means the kernel can reopen 20 windows. So move
+ * 20 entries in the VAS windows lost and reopen next 20 windows.
+ */
+ if (vcaps->close_wins > creds)
+ mv_ents = vcaps->close_wins - creds;
+
+ list_for_each_entry_safe(win, tmp, &vcaps->list, win_list) {
+ if (!mv_ents)
+ break;
+
+ mv_ents--;
+ }
+
+ list_for_each_entry_safe_from(win, tmp, &vcaps->list, win_list) {
+ /*
+ * Nothing to do on this window if it is active.
+ */
+ if (win->vas_win.status != VAS_WIN_NO_CRED_CLOSE)
+ continue;
+
+ rc = allocate_setup_window(win, (u64 *)&domain[0],
+ caps->win_type);
+ if (rc)
+ return rc;
+
+ rc = h_modify_vas_window(win);
+ if (rc)
+ goto out;
+
+ mutex_lock(&win->vas_win.task_ref.mmap_mutex);
+ /*
+ * Set window status to active
+ */
+ win->vas_win.status = VAS_WIN_ACTIVE;
+ mutex_unlock(&win->vas_win.task_ref.mmap_mutex);
+ win->win_type = caps->win_type;
+ if (!--vcaps->close_wins)
+ break;
+ }
+
+ return 0;
+out:
+ /*
+ * Window modify HCALL failed. So close the window to the
+ * hypervisor and return.
+ */
+ free_irq_setup(win);
+ h_deallocate_vas_window(win->vas_win.winid);
+ return rc;
+}
+
+/*
+ * Get new VAS capabilities when the core add/removal configuration
+ * changes. Reconfig window configurations based on the credits
+ * availability from this new capabilities.
+ */
+static int vas_reconfig_capabilties(u8 type)
+{
+ struct hv_vas_cop_feat_caps *hv_caps;
+ struct vas_cop_feat_caps *caps;
+ int lpar_creds, new_creds;
+ struct vas_caps *vcaps;
+ int rc = 0;
+
+ if (type >= VAS_MAX_FEAT_TYPE) {
+ pr_err("Invalid credit type %d\n", type);
+ return -EINVAL;
+ }
+
+ vcaps = &vascaps[type];
+ caps = &vcaps->caps;
+
+ hv_caps = kmalloc(sizeof(*hv_caps), GFP_KERNEL);
+ if (!hv_caps)
+ return -ENOMEM;
+
+ mutex_lock(&vas_pseries_mutex);
+ rc = h_query_vas_capabilities(H_QUERY_VAS_CAPABILITIES, vcaps->feat,
+ (u64)virt_to_phys(hv_caps));
+ if (rc)
+ goto out;
+
+ new_creds = be16_to_cpu(hv_caps->target_lpar_creds);
+
+ lpar_creds = atomic_read(&caps->target_creds);
+
+ atomic_set(&caps->target_creds, new_creds);
+ /*
+ * The total number of available credits may be decreased or
+ * inceased with DLPAR operation. Means some windows have to be
+ * closed / reopened. Hold the vas_pseries_mutex so that the
+ * the user space can not open new windows.
+ */
+ if (lpar_creds < new_creds) {
+ /*
+ * If the existing target credits is less than the new
+ * target, reopen windows if they are closed due to
+ * the previous DLPAR (core removal).
+ */
+ rc = reconfig_open_windows(vcaps, new_creds - lpar_creds);
+ }
+
+out:
+ mutex_unlock(&vas_pseries_mutex);
+ kfree(hv_caps);
+ return rc;
+}
+
/*
* Total number of default credits available (target_credits)
* in LPAR depends on number of cores configured. It varies based on
@@ -555,6 +694,10 @@ static int pseries_vas_notifier(struct notifier_block *nb,
if (!intserv)
return NOTIFY_OK;
+ rc = vas_reconfig_capabilties(VAS_GZIP_DEF_FEAT_TYPE);
+ if (rc)
+ pr_err("Failed reconfig VAS capabilities with DLPAR\n");
+
return rc;
}
diff --git a/arch/powerpc/platforms/pseries/vas.h b/arch/powerpc/platforms/pseries/vas.h
index 0538760d13be..45b62565955b 100644
--- a/arch/powerpc/platforms/pseries/vas.h
+++ b/arch/powerpc/platforms/pseries/vas.h
@@ -21,12 +21,6 @@
#define VAS_MOD_WIN_FLAGS (VAS_MOD_WIN_JOBS_KILL | VAS_MOD_WIN_DR | \
VAS_MOD_WIN_PR | VAS_MOD_WIN_SF)
-#define VAS_WIN_ACTIVE 0x0
-#define VAS_WIN_CLOSED 0x1
-#define VAS_WIN_INACTIVE 0x2 /* Inactive due to HW failure */
-/* Process of being modified, deallocated, or quiesced */
-#define VAS_WIN_MOD_IN_PROCESS 0x3
-
#define VAS_COPY_PASTE_USER_MODE 0x00000001
#define VAS_COP_OP_USER_MODE 0x00000010
@@ -84,6 +78,8 @@ struct vas_cop_feat_caps {
struct vas_caps {
struct vas_cop_feat_caps caps;
struct list_head list; /* List of open windows */
+ int close_wins; /* closed windows in the hypervisor for DLPAR */
+ u8 feat; /* Feature type */
};
/*
--
2.27.0
^ permalink raw reply related
* [PATCH v2 03/10] powerpc/pseries/vas: Save LPID in pseries_vas_window struct
From: Haren Myneni @ 2021-12-23 0:26 UTC (permalink / raw)
To: mpe, linuxppc-dev, npiggin
In-Reply-To: <9d1730d5e0daf39ef17196b4699294dc2ccf4a63.camel@linux.ibm.com>
The kernel sets the VAS window with partition PID when is opened in
the hypervisor. During DLPAR operation, windows can be closed and
reopened in the hypervisor when the credit is available. So saves
this PID in pseries_vas_window struct when the window is opened
initially and reuse it later during DLPAR operation.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
arch/powerpc/platforms/pseries/vas.c | 7 ++++---
arch/powerpc/platforms/pseries/vas.h | 1 +
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c
index 04a6eee2301e..fb6e6a6261a5 100644
--- a/arch/powerpc/platforms/pseries/vas.c
+++ b/arch/powerpc/platforms/pseries/vas.c
@@ -107,7 +107,6 @@ static int h_deallocate_vas_window(u64 winid)
static int h_modify_vas_window(struct pseries_vas_window *win)
{
long rc;
- u32 lpid = mfspr(SPRN_PID);
/*
* AMR value is not supported in Linux VAS implementation.
@@ -115,7 +114,7 @@ static int h_modify_vas_window(struct pseries_vas_window *win)
*/
do {
rc = plpar_hcall_norets(H_MODIFY_VAS_WINDOW,
- win->vas_win.winid, lpid, 0,
+ win->vas_win.winid, win->lpid, 0,
VAS_MOD_WIN_FLAGS, 0);
rc = hcall_return_busy_check(rc);
@@ -125,7 +124,7 @@ static int h_modify_vas_window(struct pseries_vas_window *win)
return 0;
pr_err("H_MODIFY_VAS_WINDOW error: %ld, winid %u lpid %u\n",
- rc, win->vas_win.winid, lpid);
+ rc, win->vas_win.winid, win->lpid);
return -EIO;
}
@@ -331,6 +330,8 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
}
}
+ txwin->lpid = mfspr(SPRN_PID);
+
/*
* Allocate / Deallocate window hcalls and setup / free IRQs
* have to be protected with mutex.
diff --git a/arch/powerpc/platforms/pseries/vas.h b/arch/powerpc/platforms/pseries/vas.h
index fa7ce74f1e49..0538760d13be 100644
--- a/arch/powerpc/platforms/pseries/vas.h
+++ b/arch/powerpc/platforms/pseries/vas.h
@@ -115,6 +115,7 @@ struct pseries_vas_window {
u64 domain[6]; /* Associativity domain Ids */
/* this window is allocated */
u64 util;
+ u32 lpid;
/* List of windows opened which is used for LPM */
struct list_head win_list;
--
2.27.0
^ permalink raw reply related
* [PATCH v2 02/10] powerpc/pseries/vas: Add notifier for DLPAR core removal/add
From: Haren Myneni @ 2021-12-23 0:25 UTC (permalink / raw)
To: mpe, linuxppc-dev, npiggin
In-Reply-To: <9d1730d5e0daf39ef17196b4699294dc2ccf4a63.camel@linux.ibm.com>
The hypervisor assigns credits for each LPAR based on number of
cores configured in that system. So expects to release credits
(means windows) when the core is removed. This patch adds notifier
for core removal/add so that the OS closes windows if the system
looses credits due to core removal and reopen windows when the
credits available later.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
arch/powerpc/platforms/pseries/vas.c | 34 ++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c
index ecdd21f517c0..04a6eee2301e 100644
--- a/arch/powerpc/platforms/pseries/vas.c
+++ b/arch/powerpc/platforms/pseries/vas.c
@@ -531,6 +531,36 @@ static int get_vas_capabilities(u8 feat, enum vas_cop_feat_type type,
return 0;
}
+/*
+ * Total number of default credits available (target_credits)
+ * in LPAR depends on number of cores configured. It varies based on
+ * whether processors are in shared mode or dedicated mode.
+ * Get the notifier when CPU configuration is changed with DLPAR
+ * operation so that get the new target_credits (vas default capabilities)
+ * and then update the existing windows usage if needed.
+ */
+static int pseries_vas_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct of_reconfig_data *rd = data;
+ struct device_node *dn = rd->dn;
+ const __be32 *intserv;
+ int len, rc = 0;
+
+ intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", &len);
+ /*
+ * Processor config is not changed
+ */
+ if (!intserv)
+ return NOTIFY_OK;
+
+ return rc;
+}
+
+static struct notifier_block pseries_vas_nb = {
+ .notifier_call = pseries_vas_notifier,
+};
+
static int __init pseries_vas_init(void)
{
struct hv_vas_cop_feat_caps *hv_cop_caps;
@@ -584,6 +614,10 @@ static int __init pseries_vas_init(void)
goto out_cop;
}
+ /* Processors can be added/removed only on LPAR */
+ if (copypaste_feat && firmware_has_feature(FW_FEATURE_LPAR))
+ of_reconfig_notifier_register(&pseries_vas_nb);
+
pr_info("GZIP feature is available\n");
out_cop:
--
2.27.0
^ permalink raw reply related
* [PATCH v2 01/10] powerpc/pseries/vas: Use common names in VAS capability structure
From: Haren Myneni @ 2021-12-23 0:25 UTC (permalink / raw)
To: mpe, linuxppc-dev, npiggin
In-Reply-To: <9d1730d5e0daf39ef17196b4699294dc2ccf4a63.camel@linux.ibm.com>
target/used/avail_creds provides credits usage to user space via
sysfs and the same interface can be used on PowerNV in future.
Remove "lpar" from these names so that applicable on both PowerVM
and PowerNV.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
arch/powerpc/platforms/pseries/vas.c | 10 +++++-----
arch/powerpc/platforms/pseries/vas.h | 6 +++---
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c
index b043e3936d21..ecdd21f517c0 100644
--- a/arch/powerpc/platforms/pseries/vas.c
+++ b/arch/powerpc/platforms/pseries/vas.c
@@ -303,8 +303,8 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
cop_feat_caps = &caps->caps;
- if (atomic_inc_return(&cop_feat_caps->used_lpar_creds) >
- atomic_read(&cop_feat_caps->target_lpar_creds)) {
+ if (atomic_inc_return(&cop_feat_caps->used_creds) >
+ atomic_read(&cop_feat_caps->target_creds)) {
pr_err("Credits are not available to allocate window\n");
rc = -EINVAL;
goto out;
@@ -378,7 +378,7 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
free_irq_setup(txwin);
h_deallocate_vas_window(txwin->vas_win.winid);
out:
- atomic_dec(&cop_feat_caps->used_lpar_creds);
+ atomic_dec(&cop_feat_caps->used_creds);
kfree(txwin);
return ERR_PTR(rc);
}
@@ -438,7 +438,7 @@ static int vas_deallocate_window(struct vas_window *vwin)
}
list_del(&win->win_list);
- atomic_dec(&caps->used_lpar_creds);
+ atomic_dec(&caps->used_creds);
mutex_unlock(&vas_pseries_mutex);
put_vas_user_win_ref(&vwin->task_ref);
@@ -514,7 +514,7 @@ static int get_vas_capabilities(u8 feat, enum vas_cop_feat_type type,
}
caps->max_lpar_creds = be16_to_cpu(hv_caps->max_lpar_creds);
caps->max_win_creds = be16_to_cpu(hv_caps->max_win_creds);
- atomic_set(&caps->target_lpar_creds,
+ atomic_set(&caps->target_creds,
be16_to_cpu(hv_caps->target_lpar_creds));
if (feat == VAS_GZIP_DEF_FEAT) {
caps->def_lpar_creds = be16_to_cpu(hv_caps->def_lpar_creds);
diff --git a/arch/powerpc/platforms/pseries/vas.h b/arch/powerpc/platforms/pseries/vas.h
index 4ecb3fcabd10..fa7ce74f1e49 100644
--- a/arch/powerpc/platforms/pseries/vas.h
+++ b/arch/powerpc/platforms/pseries/vas.h
@@ -72,9 +72,9 @@ struct vas_cop_feat_caps {
};
/* Total LPAR available credits. Can be different from max LPAR */
/* credits due to DLPAR operation */
- atomic_t target_lpar_creds;
- atomic_t used_lpar_creds; /* Used credits so far */
- u16 avail_lpar_creds; /* Remaining available credits */
+ atomic_t target_creds;
+ atomic_t used_creds; /* Used credits so far */
+ u16 avail_creds; /* Remaining available credits */
};
/*
--
2.27.0
^ permalink raw reply related
* [PATCH v2 00/10] powerpc/pseries/vas: NXGZIP support with DLPAR
From: Haren Myneni @ 2021-12-23 0:23 UTC (permalink / raw)
To: mpe, linuxppc-dev, npiggin
PowerPC provides HW compression with NX coprocessor. This feature
is available on both PowerNV and PowerVM and included in Linux.
Since each powerpc chip has one NX coprocessor, the VAS introduces
the concept of windows / credits to manage access to this hardware
resource. On powerVM, these limited resources should be available
across all LPARs. So the hypervisor assigns the specific credits
to each LPAR based on processor entitlement so that one LPAR does
not overload NX. The hypervisor can reject the window open request
to a partition if exceeds its credit limit (1 credit per window).
So the total number of target credits in a partition can be changed
if the core configuration is modified. The hypervisor expects the
partition to modify its window usage depends on new target
credits. For example, if the partition uses more credits than the
new target credits, it should close the excessive windows so that
the NX resource will be available to other partitions.
This patch series enables OS to support this dynamic credit
management with DLPAR core removal/add.
Core removal operation:
- Get new VAS capabilities from the hypervisor when the DLPAR
notifier is received. This capabilities provides the new target
credits based on new processor entitlement. In the case of QoS
credit changes, the notification will be issued by updating
the target_creds via sysfs.
- If the partition is already used more than the new target credits,
the kernel selects windows, unmap the current paste address and
close them in the hypervisor, It uses LIFO to identify these
windows - last windows that are opened are the first ones to be
closed.
- When the user space issue requests on these windows, NX generates
page fault on the unmap paste address. The kernel handles the
fault by returning the paste instruction failure if the window is
not active (means unmap paste). Then up to the library / user
space to fall back to SW compression or manage with the current
windows.
Core add operation:
- The kernel can see increased target credits from the new VAS
capabilities.
- Scans the window list for the closed windows in the hypervisor
due to lost credit before and selects windows based on same LIFO.
- Make these corresponding windows active and create remap with
the same VMA on the new paste address in the fault handler.
- Then the user space should expect paste successful later.
Patch 1: Define common names for sysfs target/used/avail_creds so
that same sysfs entries can be used even on PowerNV later.
Patch 2: Add VAS notifier for DLPAR core add / removal
Patch 3: Save LPID in the vas window struct during initial window
open and use it when reopen later.
Patch 4: When credits are available, reopen windows that are closed
before with core removal.
Patch 5: Close windows in the hypervisor when the partition exceeds
its usage than the new target credits.
Patch 6: If the window is closed in the hypervisor before the user
space issue the initial mmap(), return -EACCES failure.
Patch 7: Add new mmap fault handler which handles the page fault
from NX on paste address.
Patch 8: Return the paste instruction failure if the window is not
active.
Patch 9 & 10: The user space determines the credit usage with sysfs
target/avail/used_creds interfaces. drmgr uses target_creds
to notify OS for QoS credit changes.
Thanks to Nicholas Piggin and Aneesh Kumar for the valuable suggestions
on the NXGZIP design to support DLPAR operations.
Changes in v2:
- Rebase 5.16-rc5
- Use list safe functions to iterate windows list
- Changes to show the actual value in sysfs used_credits even though
some windows are inactive with core removal. Reflects -ve value in
sysfs avail_creds to let userspace know that it opened more windows
than the current maximum LPAR credits.
Haren Myneni (10):
powerpc/pseries/vas: Use common names in VAS capability structure
powerpc/pseries/vas: Add notifier for DLPAR core removal/add
powerpc/pseries/vas: Save partition PID in pseries_vas_window struct
powerpc/pseries/vas: Reopen windows with DLPAR core add
powerpc/pseries/vas: Close windows with DLPAR core removal
powerpc/vas: Map paste address only if window is active
powerpc/vas: Add paste address mmap fault handler
powerpc/vas: Return paste instruction failure if window is not active
powerpc/pseries/vas: sysfs interface to export capabilities
powerpc/pseries/vas: Write 'target_creds' for QoS credits change
arch/powerpc/include/asm/ppc-opcode.h | 2 +
arch/powerpc/include/asm/vas.h | 16 ++
arch/powerpc/platforms/book3s/vas-api.c | 129 ++++++++-
arch/powerpc/platforms/pseries/Makefile | 2 +-
arch/powerpc/platforms/pseries/vas-sysfs.c | 250 ++++++++++++++++
arch/powerpc/platforms/pseries/vas.c | 315 +++++++++++++++++++--
arch/powerpc/platforms/pseries/vas.h | 23 +-
7 files changed, 710 insertions(+), 27 deletions(-)
create mode 100644 arch/powerpc/platforms/pseries/vas-sysfs.c
--
2.27.0
^ permalink raw reply
* Re: [PATCH 1/5] crypto: sha256 - remove duplicate generic hash init function
From: Julian Calaby @ 2021-12-22 22:35 UTC (permalink / raw)
To: Tianjia Zhang
Cc: linux-s390, Thomas Bogendoerfer, Herbert Xu, Vasily Gorbik,
Heiko Carstens, linux-mips, LKML, Paul Mackerras, linux-crypto,
sparclinux, Alexander Gordeev, Christian Borntraeger,
linuxppc-dev, David S. Miller
In-Reply-To: <20211220092318.5793-2-tianjia.zhang@linux.alibaba.com>
Hi Tianjia,
On Mon, Dec 20, 2021 at 8:25 PM Tianjia Zhang
<tianjia.zhang@linux.alibaba.com> wrote:
>
> crypto_sha256_init() and sha256_base_init() are the same repeated
> implementations, remove the crypto_sha256_init() in generic
> implementation, sha224 is the same process.
>
> Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
> ---
> crypto/sha256_generic.c | 16 ++--------------
> 1 file changed, 2 insertions(+), 14 deletions(-)
>
> diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c
> index 3b377197236e..bf147b01e313 100644
> --- a/crypto/sha256_generic.c
> +++ b/crypto/sha256_generic.c
> @@ -72,7 +60,7 @@ EXPORT_SYMBOL(crypto_sha256_finup);
>
> static struct shash_alg sha256_algs[2] = { {
> .digestsize = SHA256_DIGEST_SIZE,
> - .init = crypto_sha256_init,
> + .init = sha256_base_init,
> .update = crypto_sha256_update,
> .final = crypto_sha256_final,
> .finup = crypto_sha256_finup,
> @@ -86,7 +74,7 @@ static struct shash_alg sha256_algs[2] = { {
> }
> }, {
> .digestsize = SHA224_DIGEST_SIZE,
> - .init = crypto_sha224_init,
> + .init = sha224_base_init,
> .update = crypto_sha256_update,
> .final = crypto_sha256_final,
> .finup = crypto_sha256_finup,
Aren't these two functions defined as static inline functions? It
appears that these crypto_ wrappers were added so there's "actual"
referenceable functions for these structs.
Did this actually compile?
Thanks,
--
Julian Calaby
Email: julian.calaby@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/
^ permalink raw reply
* [Bug 215389] pagealloc: memory corruption at building glibc-2.33 and running its' testsuite
From: bugzilla-daemon @ 2021-12-22 18:00 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <bug-215389-206035@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=215389
--- Comment #1 from Erhard F. (erhard_f@mailbox.org) ---
Created attachment 300115
--> https://bugzilla.kernel.org/attachment.cgi?id=300115&action=edit
kernel .config (5.15.10, PowerMac G4 DP)
--
You may reply to this email to add a comment.
You are receiving this mail because:
You are watching the assignee of the bug.
^ permalink raw reply
* [Bug 215389] New: pagealloc: memory corruption at building glibc-2.33 and running its' testsuite
From: bugzilla-daemon @ 2021-12-22 17:52 UTC (permalink / raw)
To: linuxppc-dev
https://bugzilla.kernel.org/show_bug.cgi?id=215389
Bug ID: 215389
Summary: pagealloc: memory corruption at building glibc-2.33
and running its' testsuite
Product: Platform Specific/Hardware
Version: 2.5
Kernel Version: 5.15.10
Hardware: PPC-32
OS: Linux
Tree: Mainline
Status: NEW
Severity: normal
Priority: P1
Component: PPC-32
Assignee: platform_ppc-32@kernel-bugs.osdl.org
Reporter: erhard_f@mailbox.org
Regression: No
Created attachment 300113
--> https://bugzilla.kernel.org/attachment.cgi?id=300113&action=edit
dmesg (5.15.10, PowerMac G4 DP)
Happens at running the glibc-2.33 testsuite on my G4 DP.
[...]
[ 5503.973022] pagealloc: memory corruption
[ 5503.973226] fffdfff0: 00 00 00 00 ....
[ 5503.973469] CPU: 0 PID: 15826 Comm: ld.so.1 Tainted: G W
5.15.10-gentoo-PowerMacG4 #3
[ 5503.973791] Call Trace:
[ 5503.973849] [f61edc20] [c03e8644] dump_stack_lvl+0x60/0x80 (unreliable)
[ 5503.974096] [f61edc40] [c016ece8] __kernel_unpoison_pages+0x13c/0x174
[ 5503.974320] [f61edc90] [c015aa64] post_alloc_hook+0x60/0xb4
[ 5503.974511] [f61edcb0] [c015aadc] prep_new_page+0x24/0x5c
[ 5503.974687] [f61edcd0] [c015be14] get_page_from_freelist+0x26c/0x548
[ 5503.974898] [f61edd50] [c015c5d8] __alloc_pages+0xc8/0x7a4
[ 5503.975080] [f61eddf0] [c0146470]
alloc_zeroed_user_highpage_movable.constprop.0+0x18/0x48
[ 5503.975358] [f61ede10] [c01467a8] wp_page_copy+0x58/0x4a4
[ 5503.975534] [f61ede80] [c0149df4] handle_mm_fault+0x72c/0x864
[ 5503.975725] [f61edf00] [c001a9dc] do_page_fault+0x578/0x6c8
[ 5503.975919] [f61edf30] [c000424c] DataAccess_virt+0xd4/0xe4
[ 5503.976102] --- interrupt: 300 at 0x6ffc5eb0
[ 5503.976228] NIP: 6ffc5eb0 LR: 6ffc5e84 CTR: c0335cb0
[ 5503.976383] REGS: f61edf40 TRAP: 0300 Tainted: G W
(5.15.10-gentoo-PowerMacG4)
[ 5503.976684] MSR: 0000d032 <EE,PR,ME,IR,DR,RI> CR: 840022c8 XER: 20000000
[ 5503.976929] DAR: a78032e4 DSISR: 0a000000
GPR00: 6ffc60bc af9a9650 a7a15550 0064c9ac 00896b60 00000009
bcecbe5c 001282d4
GPR08: 00899280 a78032e4 a7809068 f61edf30 240022c2 6ffece34
008a1a90 00000001
GPR16: 00000000 0064c9ac 0064c9e8 0064c980 008a1830 0064b8f4
0000000f 00000009
GPR24: 00896b60 bcecbe5c 000002c6 a7828774 a76db010 000083a7
6fff4cdc 0064c9ac
[ 5504.008476] NIP [6ffc5eb0] 0x6ffc5eb0
[ 5504.018630] LR [6ffc5e84] 0x6ffc5e84
[ 5504.028738] --- interrupt: 300
[ 5504.038956] page:ef4c8e34 refcount:1 mapcount:0 mapping:00000000 index:0x1
pfn:0x31065
[ 5504.049340] flags: 0x80000000(zone=2)
[ 5504.059763] raw: 80000000 00000100 00000122 00000000 00000001 00000000
ffffffff 00000001
[ 5504.070297] raw: 00000000
[ 5504.080511] page dumped because: pagealloc: corrupted page details
The machine stays usable afterwards. Happened also a 2nd time after a reboot,
again at building glibc-2.33 and running testsuite:
[...]
[ 2946.948834] pagealloc: memory corruption
[ 2946.949078] fffcfff0: 00 00 00 00 ....
[ 2946.949419] CPU: 1 PID: 31318 Comm: ld.so.1 Tainted: G W
5.15.10-gentoo-PowerMacG4 #3
[ 2946.949753] Call Trace:
[ 2946.949814] [f5c21b00] [c03e8644] dump_stack_lvl+0x60/0x80 (unreliable)
[ 2946.950054] [f5c21b20] [c016ece8] __kernel_unpoison_pages+0x13c/0x174
[ 2946.950281] [f5c21b70] [c015aa64] post_alloc_hook+0x60/0xb4
[ 2946.950476] [f5c21b90] [c015aadc] prep_new_page+0x24/0x5c
[ 2946.950651] [f5c21bb0] [c015be14] get_page_from_freelist+0x26c/0x548
[ 2946.950865] [f5c21c30] [c015c5d8] __alloc_pages+0xc8/0x7a4
[ 2946.951053] [f5c21cd0] [c011f6d4] pagecache_get_page+0x184/0x1fc
[ 2946.951259] [f5c21d30] [c029fd34] prepare_pages+0x80/0x14c
[ 2946.951442] [f5c21d80] [c02a28dc] btrfs_buffered_write+0x2b8/0x54c
[ 2946.951653] [f5c21e20] [c02a4700] btrfs_file_write_iter+0x340/0x368
[ 2946.951876] [f5c21e70] [c01892fc] vfs_write+0x18c/0x1dc
[ 2946.952057] [f5c21ef0] [c0189484] ksys_write+0x74/0xb8
[ 2946.952231] [f5c21f30] [c0015098] ret_from_syscall+0x0/0x28
[ 2946.952420] --- interrupt: c00 at 0x6fecc128
[ 2946.952547] NIP: 6fecc128 LR: 6fecc100 CTR: 00000001
[ 2946.952704] REGS: f5c21f40 TRAP: 0c00 Tainted: G W
(5.15.10-gentoo-PowerMacG4)
[ 2946.953008] MSR: 0000d032 <EE,PR,ME,IR,DR,RI> CR: 24022448 XER: 00000000
[ 2946.953267]
GPR00: 00000004 afad5d90 a7b83550 00000009 afad5e9c 00002000
00000000 6fecbfe8
GPR08: 0000d032 402c551a 402c5409 f5c21f30 84022448 6ffeee28
007889b0 afad8070
GPR16: afad7fa0 afad8008 00000000 00000000 00008000 00000008
00976000 001c5bcc
GPR24: 00000000 afad5e9c 00002000 00000009 afad7e9c 00000000
6ffbaff4 afad5e9c
[ 2946.975430] NIP [6fecc128] 0x6fecc128
[ 2946.985730] LR [6fecc100] 0x6fecc100
[ 2946.995992] --- interrupt: c00
[ 2947.006198] page:ef4c8e34 refcount:1 mapcount:0 mapping:00000000 index:0x1
pfn:0x31065
[ 2947.016579] flags: 0x80000000(zone=2)
[ 2947.026946] raw: 80000000 00000100 00000122 00000000 00000001 00000000
ffffffff 00000001
[ 2947.037712] raw: 00000000
[ 2947.048178] page dumped because: pagealloc: corrupted page details
--
You may reply to this email to add a comment.
You are receiving this mail because:
You are watching the assignee of the bug.
^ permalink raw reply
* Re: [PATCH v2 09/13] powerpc/ftrace: Implement CONFIG_DYNAMIC_FTRACE_WITH_ARGS
From: Miroslav Benes @ 2021-12-22 14:19 UTC (permalink / raw)
To: Christophe Leroy
Cc: mark.rutland, Petr Mladek, Joe Lawrence, broonie, Jiri Kosina,
linux-kernel@vger.kernel.org, Steven Rostedt, madvenka,
Ingo Molnar, Josh Poimboeuf, live-patching@vger.kernel.org,
Naveen N . Rao, linuxppc-dev@lists.ozlabs.org, linux-arm-kernel
In-Reply-To: <5831f711a778fcd6eb51eb5898f1faae4378b35b.1640017960.git.christophe.leroy@csgroup.eu>
On Mon, 20 Dec 2021, Christophe Leroy wrote:
> Implement CONFIG_DYNAMIC_FTRACE_WITH_ARGS. It accelerates the call
> of livepatching.
>
> Also note that powerpc being the last one to convert to
> CONFIG_DYNAMIC_FTRACE_WITH_ARGS, it will now be possible to remove
> klp_arch_set_pc() on all architectures.
Correct. We could replace it ftrace_instruction_pointer_set() and that is
it. In fact, livepatch.h in both arch/x86/include/asm/ and
arch/s390/include/asm/ could be removed with that.
On the other hand, there is arm64 live patching support being worked on
and I am not sure what their plans about DYNAMIC_FTRACE_WITH_ARGS are. The
above would make it a prerequisite.
Adding CCs... you can find the whole thread at
https://lore.kernel.org/all/cover.1640017960.git.christophe.leroy@csgroup.eu/
Miroslav
^ permalink raw reply
* Re: [PATCH v2 04/13] powerpc/ftrace: Add support for livepatch to PPC32
From: Miroslav Benes @ 2021-12-22 14:00 UTC (permalink / raw)
To: Christophe Leroy
Cc: Petr Mladek, Joe Lawrence, Jiri Kosina,
linux-kernel@vger.kernel.org, Steven Rostedt, Ingo Molnar,
Josh Poimboeuf, live-patching@vger.kernel.org, Naveen N . Rao,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <63cb094125b6a6038c65eeac2abaabbabe63addd.1640017960.git.christophe.leroy@csgroup.eu>
On Mon, 20 Dec 2021, Christophe Leroy wrote:
> PPC64 needs some special logic to properly set up the TOC.
> See commit 85baa095497f ("powerpc/livepatch: Add live patching support
> on ppc64le") for details.
>
> PPC32 doesn't have TOC so it doesn't need that logic, so adding
> LIVEPATCH support is straight forward.
>
> Add CONFIG_LIVEPATCH_64 and move livepatch stack logic into that item.
>
> Livepatch sample modules all work.
Great.
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
FWIW the patch looks good to me.
Miroslav
^ permalink raw reply
* Re: [PATCH v2 01/13] livepatch: Fix build failure on 32 bits processors
From: Miroslav Benes @ 2021-12-22 13:47 UTC (permalink / raw)
To: Christophe Leroy
Cc: Petr Mladek, Joe Lawrence, Jiri Kosina,
linux-kernel@vger.kernel.org, Steven Rostedt, Ingo Molnar,
Josh Poimboeuf, live-patching@vger.kernel.org, Naveen N . Rao,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <5288e11b018a762ea3351cc8fb2d4f15093a4457.1640017960.git.christophe.leroy@csgroup.eu>
On Mon, 20 Dec 2021, Christophe Leroy wrote:
> Trying to build livepatch on powerpc/32 results in:
>
> kernel/livepatch/core.c: In function 'klp_resolve_symbols':
> kernel/livepatch/core.c:221:23: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
> 221 | sym = (Elf64_Sym *)sechdrs[symndx].sh_addr + ELF_R_SYM(relas[i].r_info);
> | ^
> kernel/livepatch/core.c:221:21: error: assignment to 'Elf32_Sym *' {aka 'struct elf32_sym *'} from incompatible pointer type 'Elf64_Sym *' {aka 'struct elf64_sym *'} [-Werror=incompatible-pointer-types]
> 221 | sym = (Elf64_Sym *)sechdrs[symndx].sh_addr + ELF_R_SYM(relas[i].r_info);
> | ^
> kernel/livepatch/core.c: In function 'klp_apply_section_relocs':
> kernel/livepatch/core.c:312:35: error: passing argument 1 of 'klp_resolve_symbols' from incompatible pointer type [-Werror=incompatible-pointer-types]
> 312 | ret = klp_resolve_symbols(sechdrs, strtab, symndx, sec, sec_objname);
> | ^~~~~~~
> | |
> | Elf32_Shdr * {aka struct elf32_shdr *}
> kernel/livepatch/core.c:193:44: note: expected 'Elf64_Shdr *' {aka 'struct elf64_shdr *'} but argument is of type 'Elf32_Shdr *' {aka 'struct elf32_shdr *'}
> 193 | static int klp_resolve_symbols(Elf64_Shdr *sechdrs, const char *strtab,
> | ~~~~~~~~~~~~^~~~~~~
>
> Fix it by using the right types instead of forcing 64 bits types.
>
> Fixes: 7c8e2bdd5f0d ("livepatch: Apply vmlinux-specific KLP relocations early")
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> Acked-by: Petr Mladek <pmladek@suse.com>
Acked-by: Miroslav Benes <mbenes@suse.cz>
M
^ permalink raw reply
* Re: [PATCH v1 06/11] powerpc/code-patching: Fix patch_branch() return on out-of-range failure
From: Christophe Leroy @ 2021-12-22 13:16 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman
Cc: linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org
In-Reply-To: <8540cb64b1f06710eaf41e3835c7ba3e21fa2b05.1638446239.git.christophe.leroy@csgroup.eu>
Le 02/12/2021 à 13:00, Christophe Leroy a écrit :
> Do not silentely ignore a failure of create_branch() in
> patch_branch(). Return -ERANGE.
>
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
From
https://patchwork.ozlabs.org/project/linuxppc-dev/patch/4940b03de220d1dfe2c6b47a41e60925497ce125.1630657331.git.christophe.leroy@csgroup.eu/
Reviewed-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
> ---
> arch/powerpc/lib/code-patching.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c
> index a43ca22313ee..e7a2a41ae8eb 100644
> --- a/arch/powerpc/lib/code-patching.c
> +++ b/arch/powerpc/lib/code-patching.c
> @@ -191,7 +191,9 @@ int patch_branch(u32 *addr, unsigned long target, int flags)
> {
> ppc_inst_t instr;
>
> - create_branch(&instr, addr, target, flags);
> + if (create_branch(&instr, addr, target, flags))
> + return -ERANGE;
> +
> return patch_instruction(addr, instr);
> }
>
>
^ 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