s390/qdio: Move memory alloc/pointer arithmetic for slib and sl into one place
authorBenjamin Block <bblock@linux.ibm.com>
Wed, 5 Apr 2023 14:28:34 +0000 (16:28 +0200)
committerAlexander Gordeev <agordeev@linux.ibm.com>
Fri, 3 Jan 2025 10:00:53 +0000 (11:00 +0100)
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 <bblock@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
drivers/s390/cio/qdio.h
drivers/s390/cio/qdio_setup.c

index 5c09f2ef874e921511e7f566f0c36ff46d36e744..4bd4c00c9c0ca6b635c2d890f17c607dcdb6018f 100644 (file)
@@ -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)));
 
index 1f532b112194bd82f129d2a863a047677c09fdfe..ea09aadaae4ecac74c30b80bf2746218af7b2c36 100644 (file)
@@ -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++)