Home Home > GIT Browse > SLE15-SP1
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Tesarik <ptesarik@suse.cz>2019-06-07 12:44:54 +0200
committerPetr Tesarik <ptesarik@suse.cz>2019-06-14 17:58:44 +0200
commit3a4d58aae6adce6dce1ecb114ad5db0c4717bf71 (patch)
treeaedf274522aa922d1559aa601024c1cd7ae86a4c
parentb4d7cdd425ff090cb02f1ced5b29d393724e6a1e (diff)
s390/airq: provide cacheline aligned ivs (jsc#SLE-5789
FATE#327042 bsc#1134730 LTC#173388).
-rw-r--r--patches.arch/s390-airq-provide-cacheline-aligned-ivs114
-rw-r--r--series.conf1
2 files changed, 115 insertions, 0 deletions
diff --git a/patches.arch/s390-airq-provide-cacheline-aligned-ivs b/patches.arch/s390-airq-provide-cacheline-aligned-ivs
new file mode 100644
index 0000000000..cb6090cd53
--- /dev/null
+++ b/patches.arch/s390-airq-provide-cacheline-aligned-ivs
@@ -0,0 +1,114 @@
+From: Sebastian Ott <sebott@linux.ibm.com>
+Date: Wed, 27 Feb 2019 13:56:08 +0100
+Subject: s390/airq: provide cacheline aligned ivs
+Git-commit: 414cbd1e3d14ec0e60666a0fb9d8ae2d77eb7c63
+Patch-mainline: v5.2-rc1
+References: jsc#SLE-5789 FATE#327042 bsc#1134730 LTC#173388
+
+Provide the ability to create cachesize aligned interrupt vectors.
+These will be used for per-CPU interrupt vectors.
+
+Signed-off-by: Sebastian Ott <sebott@linux.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Acked-by: Petr Tesarik <ptesarik@suse.com>
+---
+ arch/s390/include/asm/airq.h | 10 ++++++----
+ drivers/s390/cio/airq.c | 39 ++++++++++++++++++++++++++++++++++-----
+ 2 files changed, 40 insertions(+), 9 deletions(-)
+
+--- a/arch/s390/include/asm/airq.h
++++ b/arch/s390/include/asm/airq.h
+@@ -34,13 +34,15 @@ struct airq_iv {
+ unsigned int *data; /* 32 bit value associated with each bit */
+ unsigned long bits; /* Number of bits in the vector */
+ unsigned long end; /* Number of highest allocated bit + 1 */
++ unsigned long flags; /* Allocation flags */
+ spinlock_t lock; /* Lock to protect alloc & free */
+ };
+
+-#define AIRQ_IV_ALLOC 1 /* Use an allocation bit mask */
+-#define AIRQ_IV_BITLOCK 2 /* Allocate the lock bit mask */
+-#define AIRQ_IV_PTR 4 /* Allocate the ptr array */
+-#define AIRQ_IV_DATA 8 /* Allocate the data array */
++#define AIRQ_IV_ALLOC 1 /* Use an allocation bit mask */
++#define AIRQ_IV_BITLOCK 2 /* Allocate the lock bit mask */
++#define AIRQ_IV_PTR 4 /* Allocate the ptr array */
++#define AIRQ_IV_DATA 8 /* Allocate the data array */
++#define AIRQ_IV_CACHELINE 16 /* Cacheline alignment for the vector */
+
+ struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags);
+ void airq_iv_release(struct airq_iv *iv);
+--- a/drivers/s390/cio/airq.c
++++ b/drivers/s390/cio/airq.c
+@@ -26,6 +26,8 @@
+ static DEFINE_SPINLOCK(airq_lists_lock);
+ static struct hlist_head airq_lists[MAX_ISC+1];
+
++static struct kmem_cache *airq_iv_cache;
++
+ /**
+ * register_adapter_interrupt() - register adapter interrupt handler
+ * @airq: pointer to adapter interrupt descriptor
+@@ -128,10 +130,21 @@ struct airq_iv *airq_iv_create(unsigned
+ if (!iv)
+ goto out;
+ iv->bits = bits;
++ iv->flags = flags;
+ size = BITS_TO_LONGS(bits) * sizeof(unsigned long);
+- iv->vector = kzalloc(size, GFP_KERNEL);
+- if (!iv->vector)
+- goto out_free;
++
++ if (flags & AIRQ_IV_CACHELINE) {
++ if ((cache_line_size() * BITS_PER_BYTE) < bits)
++ goto out_free;
++
++ iv->vector = kmem_cache_zalloc(airq_iv_cache, GFP_KERNEL);
++ if (!iv->vector)
++ goto out_free;
++ } else {
++ iv->vector = kzalloc(size, GFP_KERNEL);
++ if (!iv->vector)
++ goto out_free;
++ }
+ if (flags & AIRQ_IV_ALLOC) {
+ iv->avail = kmalloc(size, GFP_KERNEL);
+ if (!iv->avail)
+@@ -164,7 +177,10 @@ out_free:
+ kfree(iv->ptr);
+ kfree(iv->bitlock);
+ kfree(iv->avail);
+- kfree(iv->vector);
++ if (iv->flags & AIRQ_IV_CACHELINE)
++ kmem_cache_free(airq_iv_cache, iv->vector);
++ else
++ kfree(iv->vector);
+ kfree(iv);
+ out:
+ return NULL;
+@@ -180,7 +196,10 @@ void airq_iv_release(struct airq_iv *iv)
+ kfree(iv->data);
+ kfree(iv->ptr);
+ kfree(iv->bitlock);
+- kfree(iv->vector);
++ if (iv->flags & AIRQ_IV_CACHELINE)
++ kmem_cache_free(airq_iv_cache, iv->vector);
++ else
++ kfree(iv->vector);
+ kfree(iv->avail);
+ kfree(iv);
+ }
+@@ -274,3 +293,13 @@ unsigned long airq_iv_scan(struct airq_i
+ return bit;
+ }
+ EXPORT_SYMBOL(airq_iv_scan);
++
++static int __init airq_init(void)
++{
++ airq_iv_cache = kmem_cache_create("airq_iv_cache", cache_line_size(),
++ cache_line_size(), 0, NULL);
++ if (!airq_iv_cache)
++ return -ENOMEM;
++ return 0;
++}
++subsys_initcall(airq_init);
diff --git a/series.conf b/series.conf
index 388fd54923..0c6a1ef152 100644
--- a/series.conf
+++ b/series.conf
@@ -46258,6 +46258,7 @@
patches.arch/s390-sclp-detect-dirq-facility
patches.arch/s390-airq-recognize-directed-interrupts
patches.arch/s390-pci-clarify-interrupt-vector-usage
+ patches.arch/s390-airq-provide-cacheline-aligned-ivs
patches.fixes/ACPI-button-reinitialize-button-state-upon-resume.patch
patches.fixes/ACPI-property-restore-_DSD-data-subnodes-GUID-commen.patch
patches.fixes/ACPI-property-fix-handling-of-data_nodes-in-acpi_get.patch