hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/s390/cio/qdio_thinint.c
....@@ -39,14 +39,6 @@
3939 static LIST_HEAD(tiq_list);
4040 static DEFINE_MUTEX(tiq_list_lock);
4141
42
-/* Adapter interrupt definitions */
43
-static void tiqdio_thinint_handler(struct airq_struct *airq);
44
-
45
-static struct airq_struct tiqdio_airq = {
46
- .handler = tiqdio_thinint_handler,
47
- .isc = QDIO_AIRQ_ISC,
48
-};
49
-
5042 static struct indicator_t *q_indicators;
5143
5244 u64 last_ai_time;
....@@ -74,31 +66,20 @@
7466 atomic_dec(&ind->count);
7567 }
7668
77
-void tiqdio_add_input_queues(struct qdio_irq *irq_ptr)
69
+void tiqdio_add_device(struct qdio_irq *irq_ptr)
7870 {
7971 mutex_lock(&tiq_list_lock);
80
- list_add_rcu(&irq_ptr->input_qs[0]->entry, &tiq_list);
72
+ list_add_rcu(&irq_ptr->entry, &tiq_list);
8173 mutex_unlock(&tiq_list_lock);
8274 }
8375
84
-void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
76
+void tiqdio_remove_device(struct qdio_irq *irq_ptr)
8577 {
86
- struct qdio_q *q;
87
-
88
- q = irq_ptr->input_qs[0];
89
- if (!q)
90
- return;
91
-
9278 mutex_lock(&tiq_list_lock);
93
- list_del_rcu(&q->entry);
79
+ list_del_rcu(&irq_ptr->entry);
9480 mutex_unlock(&tiq_list_lock);
9581 synchronize_rcu();
96
- INIT_LIST_HEAD(&q->entry);
97
-}
98
-
99
-static inline int has_multiple_inq_on_dsci(struct qdio_irq *irq_ptr)
100
-{
101
- return irq_ptr->nr_input_qs > 1;
82
+ INIT_LIST_HEAD(&irq_ptr->entry);
10283 }
10384
10485 static inline int references_shared_dsci(struct qdio_irq *irq_ptr)
....@@ -106,26 +87,11 @@
10687 return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
10788 }
10889
109
-static inline int shared_ind(struct qdio_irq *irq_ptr)
110
-{
111
- return references_shared_dsci(irq_ptr) ||
112
- has_multiple_inq_on_dsci(irq_ptr);
113
-}
114
-
115
-void clear_nonshared_ind(struct qdio_irq *irq_ptr)
116
-{
117
- if (!is_thinint_irq(irq_ptr))
118
- return;
119
- if (shared_ind(irq_ptr))
120
- return;
121
- xchg(irq_ptr->dsci, 0);
122
-}
123
-
12490 int test_nonshared_ind(struct qdio_irq *irq_ptr)
12591 {
12692 if (!is_thinint_irq(irq_ptr))
12793 return 0;
128
- if (shared_ind(irq_ptr))
94
+ if (references_shared_dsci(irq_ptr))
12995 return 0;
13096 if (*irq_ptr->dsci)
13197 return 1;
....@@ -145,43 +111,36 @@
145111 struct qdio_q *q;
146112 int i;
147113
148
- if (!references_shared_dsci(irq) &&
149
- has_multiple_inq_on_dsci(irq))
114
+ if (!references_shared_dsci(irq))
150115 xchg(irq->dsci, 0);
151116
117
+ if (irq->irq_poll) {
118
+ if (!test_and_set_bit(QDIO_IRQ_DISABLED, &irq->poll_state))
119
+ irq->irq_poll(irq->cdev, irq->int_parm);
120
+ else
121
+ QDIO_PERF_STAT_INC(irq, int_discarded);
122
+
123
+ return;
124
+ }
125
+
152126 for_each_input_queue(irq, q, i) {
153
- if (q->u.in.queue_start_poll) {
154
- /* skip if polling is enabled or already in work */
155
- if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
156
- &q->u.in.queue_irq_state)) {
157
- qperf_inc(q, int_discarded);
158
- continue;
159
- }
160
-
161
- /* avoid dsci clear here, done after processing */
162
- q->u.in.queue_start_poll(irq->cdev, q->nr,
163
- irq->int_parm);
164
- } else {
165
- if (!shared_ind(irq))
166
- xchg(irq->dsci, 0);
167
-
168
- /*
169
- * Call inbound processing but not directly
170
- * since that could starve other thinint queues.
171
- */
172
- tasklet_schedule(&q->tasklet);
173
- }
127
+ /*
128
+ * Call inbound processing but not directly
129
+ * since that could starve other thinint queues.
130
+ */
131
+ tasklet_schedule(&q->tasklet);
174132 }
175133 }
176134
177135 /**
178136 * tiqdio_thinint_handler - thin interrupt handler for qdio
179137 * @airq: pointer to adapter interrupt descriptor
138
+ * @floating: flag to recognize floating vs. directed interrupts (unused)
180139 */
181
-static void tiqdio_thinint_handler(struct airq_struct *airq)
140
+static void tiqdio_thinint_handler(struct airq_struct *airq, bool floating)
182141 {
183142 u32 si_used = clear_shared_ind();
184
- struct qdio_q *q;
143
+ struct qdio_irq *irq;
185144
186145 last_ai_time = S390_lowcore.int_clock;
187146 inc_irq_stat(IRQIO_QAI);
....@@ -189,12 +148,8 @@
189148 /* protect tiq_list entries, only changed in activate or shutdown */
190149 rcu_read_lock();
191150
192
- /* check for work on all inbound thinint queues */
193
- list_for_each_entry_rcu(q, &tiq_list, entry) {
194
- struct qdio_irq *irq;
195
-
151
+ list_for_each_entry_rcu(irq, &tiq_list, entry) {
196152 /* only process queues from changed sets */
197
- irq = q->irq_ptr;
198153 if (unlikely(references_shared_dsci(irq))) {
199154 if (!si_used)
200155 continue;
....@@ -203,10 +158,15 @@
203158
204159 tiqdio_call_inq_handlers(irq);
205160
206
- qperf_inc(q, adapter_int);
161
+ QDIO_PERF_STAT_INC(irq, adapter_int);
207162 }
208163 rcu_read_unlock();
209164 }
165
+
166
+static struct airq_struct tiqdio_airq = {
167
+ .handler = tiqdio_thinint_handler,
168
+ .isc = QDIO_AIRQ_ISC,
169
+};
210170
211171 static int set_subchannel_ind(struct qdio_irq *irq_ptr, int reset)
212172 {
....@@ -223,7 +183,7 @@
223183 }
224184
225185 rc = chsc_sadc(irq_ptr->schid, scssc, summary_indicator_addr,
226
- subchannel_indicator_addr);
186
+ subchannel_indicator_addr, tiqdio_airq.isc);
227187 if (rc) {
228188 DBF_ERROR("%4x SSI r:%4x", irq_ptr->schid.sch_no,
229189 scssc->response.code);
....@@ -235,34 +195,6 @@
235195 DBF_HEX(&subchannel_indicator_addr, sizeof(subchannel_indicator_addr));
236196 out:
237197 return rc;
238
-}
239
-
240
-/* allocate non-shared indicators and shared indicator */
241
-int __init tiqdio_allocate_memory(void)
242
-{
243
- q_indicators = kcalloc(TIQDIO_NR_INDICATORS,
244
- sizeof(struct indicator_t),
245
- GFP_KERNEL);
246
- if (!q_indicators)
247
- return -ENOMEM;
248
- return 0;
249
-}
250
-
251
-void tiqdio_free_memory(void)
252
-{
253
- kfree(q_indicators);
254
-}
255
-
256
-int __init tiqdio_register_thinints(void)
257
-{
258
- int rc;
259
-
260
- rc = register_adapter_interrupt(&tiqdio_airq);
261
- if (rc) {
262
- DBF_EVENT("RTI:%x", rc);
263
- return rc;
264
- }
265
- return 0;
266198 }
267199
268200 int qdio_establish_thinint(struct qdio_irq *irq_ptr)
....@@ -292,8 +224,27 @@
292224 put_indicator(irq_ptr->dsci);
293225 }
294226
295
-void __exit tiqdio_unregister_thinints(void)
227
+int __init qdio_thinint_init(void)
228
+{
229
+ int rc;
230
+
231
+ q_indicators = kcalloc(TIQDIO_NR_INDICATORS, sizeof(struct indicator_t),
232
+ GFP_KERNEL);
233
+ if (!q_indicators)
234
+ return -ENOMEM;
235
+
236
+ rc = register_adapter_interrupt(&tiqdio_airq);
237
+ if (rc) {
238
+ DBF_EVENT("RTI:%x", rc);
239
+ kfree(q_indicators);
240
+ return rc;
241
+ }
242
+ return 0;
243
+}
244
+
245
+void __exit qdio_thinint_exit(void)
296246 {
297247 WARN_ON(!list_empty(&tiq_list));
298248 unregister_adapter_interrupt(&tiqdio_airq);
249
+ kfree(q_indicators);
299250 }