From 30e037ad7eb44bcf56fb1a845cc718d50c363310 Mon Sep 17 00:00:00 2001 From: Benjamin Block Date: Wed, 5 Apr 2023 16:28:34 +0200 Subject: [PATCH] s390/qdio: Move memory alloc/pointer arithmetic for slib and sl into one place Instead of distributing the memory allocation and pointer arithmetic to place slib and sl on the page that is allocated for them over multiple functions and comments, move both into the same context directly next to each other, so that the knowledge of how this is done is immediately visible. The actual layout in memory doesn't change with this, just the structure of the code to achieve it. Signed-off-by: Benjamin Block Reviewed-by: Steffen Maier Reviewed-by: Alexandra Winter Signed-off-by: Alexander Gordeev --- drivers/s390/cio/qdio.h | 7 +++---- drivers/s390/cio/qdio_setup.c | 19 +++++++++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 5c09f2ef874e9..4bd4c00c9c0ca 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -210,11 +210,10 @@ struct qdio_q { qdio_handler_t (*handler); struct qdio_irq *irq_ptr; + + /* memory page (PAGE_SIZE) used to place slib and sl on */ + void *sl_page; struct sl *sl; - /* - * A page is allocated under this pointer and used for slib and sl. - * slib is 2048 bytes big and sl points to offset PAGE_SIZE / 2. - */ struct slib *slib; } __attribute__ ((aligned(256))); diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index 1f532b112194b..ea09aadaae4ec 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c @@ -83,7 +83,7 @@ static void __qdio_free_queues(struct qdio_q **queues, unsigned int count) for (i = 0; i < count; i++) { q = queues[i]; - free_page((unsigned long) q->slib); + free_page((unsigned long)q->sl_page); kmem_cache_free(qdio_q_cache, q); } } @@ -109,12 +109,16 @@ static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues) return -ENOMEM; } - q->slib = (struct slib *) __get_free_page(GFP_KERNEL); - if (!q->slib) { + q->sl_page = (void *)__get_free_page(GFP_KERNEL); + if (!q->sl_page) { kmem_cache_free(qdio_q_cache, q); __qdio_free_queues(irq_ptr_qs, i); return -ENOMEM; } + q->slib = q->sl_page; + /* As per architecture: SLIB is 2K bytes long, and SL 1K. */ + q->sl = (struct sl *)(q->slib + 1); + irq_ptr_qs[i] = q; } return 0; @@ -142,11 +146,15 @@ int qdio_allocate_qs(struct qdio_irq *irq_ptr, int nr_input_qs, int nr_output_qs static void setup_queues_misc(struct qdio_q *q, struct qdio_irq *irq_ptr, qdio_handler_t *handler, int i) { - struct slib *slib = q->slib; + struct slib *const slib = q->slib; + void *const sl_page = q->sl_page; + struct sl *const sl = q->sl; /* queue must be cleared for qdio_establish */ memset(q, 0, sizeof(*q)); - memset(slib, 0, PAGE_SIZE); + memset(sl_page, 0, PAGE_SIZE); + q->sl_page = sl_page; + q->sl = sl; q->slib = slib; q->irq_ptr = irq_ptr; q->mask = 1 << (31 - i); @@ -161,7 +169,6 @@ static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr, int j; DBF_HEX(&q, sizeof(void *)); - q->sl = (struct sl *)((char *)q->slib + PAGE_SIZE / 2); /* fill in sbal */ for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) -- 2.39.5