]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
s390/qdio: simplify thinint device registration
authorJulian Wiedmann <jwi@linux.ibm.com>
Tue, 23 Jul 2019 09:55:27 +0000 (11:55 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Thu, 31 Oct 2019 16:20:51 +0000 (17:20 +0100)
On an interrupt, tiqdio_thinint_handler() walks a list of all objects
that might require attention, and checks their DSCI. This list is
awkwardly built from Input Queues, even though the IRQs are per-device
and the queue is then only used to dereference its qdio_irq parent.

To simplify the logic, change the code so that tiq_list contains
qdio_irq entries.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
drivers/s390/cio/qdio.h
drivers/s390/cio/qdio_main.c
drivers/s390/cio/qdio_setup.c
drivers/s390/cio/qdio_thinint.c

index a6cbbd8e928ccf3c01a1cd921a7c7d9c5597b9f4..64cc14e47e3550f4545ecbbd5d6171b5ce36793a 100644 (file)
@@ -252,9 +252,6 @@ struct qdio_q {
        /* input or output queue */
        int is_input_q;
 
-       /* list of thinint input queues */
-       struct list_head entry;
-
        /* upper-layer program handler */
        qdio_handler_t (*handler);
 
@@ -272,6 +269,7 @@ struct qdio_irq {
        struct qib qib;
        u32 *dsci;              /* address of device state change indicator */
        struct ccw_device *cdev;
+       struct list_head entry;         /* list of thinint devices */
        struct dentry *debugfs_dev;
        struct dentry *debugfs_perf;
 
@@ -373,8 +371,8 @@ extern u64 last_ai_time;
 void qdio_setup_thinint(struct qdio_irq *irq_ptr);
 int qdio_establish_thinint(struct qdio_irq *irq_ptr);
 void qdio_shutdown_thinint(struct qdio_irq *irq_ptr);
-void tiqdio_add_input_queues(struct qdio_irq *irq_ptr);
-void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr);
+void tiqdio_add_device(struct qdio_irq *irq_ptr);
+void tiqdio_remove_device(struct qdio_irq *irq_ptr);
 void tiqdio_inbound_processing(unsigned long q);
 int tiqdio_allocate_memory(void);
 void tiqdio_free_memory(void);
index 8512255ddc338f7beeb2a10dd42d970776436673..d0c85862c2586fbdd74315d5030b2de6592bf35d 100644 (file)
@@ -1162,7 +1162,7 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
         */
        qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
 
-       tiqdio_remove_input_queues(irq_ptr);
+       tiqdio_remove_device(irq_ptr);
        qdio_shutdown_queues(cdev);
        qdio_shutdown_debug_entries(irq_ptr);
 
@@ -1284,6 +1284,7 @@ int qdio_allocate(struct qdio_initialize *init_data)
                             init_data->no_output_qs))
                goto out_rel;
 
+       INIT_LIST_HEAD(&irq_ptr->entry);
        init_data->cdev->private->qdio_data = irq_ptr;
        qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
        return 0;
@@ -1428,7 +1429,7 @@ int qdio_activate(struct ccw_device *cdev)
        }
 
        if (is_thinint_irq(irq_ptr))
-               tiqdio_add_input_queues(irq_ptr);
+               tiqdio_add_device(irq_ptr);
 
        /* wait for subchannel to become active */
        msleep(5);
index cd164886132fdc048abe3fa36c2f0f6bb8dcba50..dc430bd86ade93039579f2d0d32e370857dfab40 100644 (file)
@@ -150,7 +150,6 @@ static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues)
                        return -ENOMEM;
                }
                irq_ptr_qs[i] = q;
-               INIT_LIST_HEAD(&q->entry);
        }
        return 0;
 }
@@ -179,7 +178,6 @@ static void setup_queues_misc(struct qdio_q *q, struct qdio_irq *irq_ptr,
        q->mask = 1 << (31 - i);
        q->nr = i;
        q->handler = handler;
-       INIT_LIST_HEAD(&q->entry);
 }
 
 static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr,
index 92281f7e49012ed0f2387209886ca588127921c2..7c4e4ec08a12c5bb678c7a739b7919d8a3e3be1f 100644 (file)
@@ -66,26 +66,20 @@ static void put_indicator(u32 *addr)
        atomic_dec(&ind->count);
 }
 
-void tiqdio_add_input_queues(struct qdio_irq *irq_ptr)
+void tiqdio_add_device(struct qdio_irq *irq_ptr)
 {
        mutex_lock(&tiq_list_lock);
-       list_add_rcu(&irq_ptr->input_qs[0]->entry, &tiq_list);
+       list_add_rcu(&irq_ptr->entry, &tiq_list);
        mutex_unlock(&tiq_list_lock);
 }
 
-void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
+void tiqdio_remove_device(struct qdio_irq *irq_ptr)
 {
-       struct qdio_q *q;
-
-       q = irq_ptr->input_qs[0];
-       if (!q)
-               return;
-
        mutex_lock(&tiq_list_lock);
-       list_del_rcu(&q->entry);
+       list_del_rcu(&irq_ptr->entry);
        mutex_unlock(&tiq_list_lock);
        synchronize_rcu();
-       INIT_LIST_HEAD(&q->entry);
+       INIT_LIST_HEAD(&irq_ptr->entry);
 }
 
 static inline int has_multiple_inq_on_dsci(struct qdio_irq *irq_ptr)
@@ -174,7 +168,7 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq)
 static void tiqdio_thinint_handler(struct airq_struct *airq, bool floating)
 {
        u32 si_used = clear_shared_ind();
-       struct qdio_q *q;
+       struct qdio_irq *irq;
 
        last_ai_time = S390_lowcore.int_clock;
        inc_irq_stat(IRQIO_QAI);
@@ -182,12 +176,8 @@ static void tiqdio_thinint_handler(struct airq_struct *airq, bool floating)
        /* protect tiq_list entries, only changed in activate or shutdown */
        rcu_read_lock();
 
-       /* check for work on all inbound thinint queues */
-       list_for_each_entry_rcu(q, &tiq_list, entry) {
-               struct qdio_irq *irq;
-
+       list_for_each_entry_rcu(irq, &tiq_list, entry) {
                /* only process queues from changed sets */
-               irq = q->irq_ptr;
                if (unlikely(references_shared_dsci(irq))) {
                        if (!si_used)
                                continue;