]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.arch/s390-17-perf-04-qdio_move_adapter_interrupt_tasklet_code.patch
Fix oinkmaster patch.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / s390-17-perf-04-qdio_move_adapter_interrupt_tasklet_code.patch
CommitLineData
82094b55
AF
1From: Gerald Schaefer <geraldsc@de.ibm.com>
2Subject: [PATCH] qdio: move adapter interrupt tasklet code
3References: bnc#532063,LTC#55526
4
5From: Jan Glauber <jang@linux.vnet.ibm.com>
6
7Move the adapter interrupt tasklet function to the qdio main code
8since all the functions used by the tasklet are located there.
9
10Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
11
12Acked-by: John Jolly <jjolly@suse.de>
13
14---
15 drivers/s390/cio/qdio.h | 11 -----
16 drivers/s390/cio/qdio_debug.c | 3 -
17 drivers/s390/cio/qdio_main.c | 83 ++++++++++++++++++++++++++++++++++------
18 drivers/s390/cio/qdio_thinint.c | 57 ---------------------------
19 4 files changed, 75 insertions(+), 79 deletions(-)
20
21Index: linux-sles11/drivers/s390/cio/qdio.h
22===================================================================
23--- linux-sles11.orig/drivers/s390/cio/qdio.h
24+++ linux-sles11/drivers/s390/cio/qdio.h
25@@ -348,15 +348,6 @@ static inline unsigned long long get_use
26 ((bufnr - dec) & QDIO_MAX_BUFFERS_MASK)
27
28 /* prototypes for thin interrupt */
29-void qdio_sync_after_thinint(struct qdio_q *q);
30-int get_buf_state(struct qdio_q *q, unsigned int bufnr, unsigned char *state,
31- int auto_ack);
32-void qdio_check_outbound_after_thinint(struct qdio_q *q);
33-int qdio_inbound_q_moved(struct qdio_q *q);
34-void qdio_kick_inbound_handler(struct qdio_q *q);
35-void qdio_stop_polling(struct qdio_q *q);
36-int qdio_siga_sync_q(struct qdio_q *q);
37-
38 void qdio_setup_thinint(struct qdio_irq *irq_ptr);
39 int qdio_establish_thinint(struct qdio_irq *irq_ptr);
40 void qdio_shutdown_thinint(struct qdio_irq *irq_ptr);
41@@ -389,4 +380,6 @@ void qdio_setup_destroy_sysfs(struct ccw
42 int qdio_setup_init(void);
43 void qdio_setup_exit(void);
44
45+int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr,
46+ unsigned char *state);
47 #endif /* _CIO_QDIO_H */
48Index: linux-sles11/drivers/s390/cio/qdio_debug.c
49===================================================================
50--- linux-sles11.orig/drivers/s390/cio/qdio_debug.c
51+++ linux-sles11/drivers/s390/cio/qdio_debug.c
52@@ -69,9 +69,8 @@ static int qstat_show(struct seq_file *m
53 seq_printf(m, "slsb buffer states:\n");
54 seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n");
55
56- qdio_siga_sync_q(q);
57 for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {
58- get_buf_state(q, i, &state, 0);
59+ debug_get_buf_state(q, i, &state);
60 switch (state) {
61 case SLSB_P_INPUT_NOT_INIT:
62 case SLSB_P_OUTPUT_NOT_INIT:
63Index: linux-sles11/drivers/s390/cio/qdio_main.c
64===================================================================
65--- linux-sles11.orig/drivers/s390/cio/qdio_main.c
66+++ linux-sles11/drivers/s390/cio/qdio_main.c
67@@ -225,8 +225,8 @@ static inline int get_buf_states(struct
68 return i;
69 }
70
71-inline int get_buf_state(struct qdio_q *q, unsigned int bufnr,
72- unsigned char *state, int auto_ack)
73+static inline int get_buf_state(struct qdio_q *q, unsigned int bufnr,
74+ unsigned char *state, int auto_ack)
75 {
76 return get_buf_states(q, bufnr, state, 1, auto_ack);
77 }
78@@ -270,7 +270,7 @@ void qdio_init_buf_states(struct qdio_ir
79 QDIO_MAX_BUFFERS_PER_Q);
80 }
81
82-static int qdio_siga_sync(struct qdio_q *q, unsigned int output,
83+static inline int qdio_siga_sync(struct qdio_q *q, unsigned int output,
84 unsigned int input)
85 {
86 int cc;
87@@ -287,7 +287,7 @@ static int qdio_siga_sync(struct qdio_q
88 return cc;
89 }
90
91-inline int qdio_siga_sync_q(struct qdio_q *q)
92+static inline int qdio_siga_sync_q(struct qdio_q *q)
93 {
94 if (q->is_input_q)
95 return qdio_siga_sync(q, 0, q->mask);
96@@ -349,8 +349,7 @@ static inline int qdio_siga_input(struct
97 return cc;
98 }
99
100-/* called from thinint inbound handler */
101-void qdio_sync_after_thinint(struct qdio_q *q)
102+static inline void qdio_sync_after_thinint(struct qdio_q *q)
103 {
104 if (pci_out_supported(q)) {
105 if (need_siga_sync_thinint(q))
106@@ -361,7 +360,14 @@ void qdio_sync_after_thinint(struct qdio
107 qdio_siga_sync_q(q);
108 }
109
110-inline void qdio_stop_polling(struct qdio_q *q)
111+int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr,
112+ unsigned char *state)
113+{
114+ qdio_siga_sync_q(q);
115+ return get_buf_states(q, bufnr, state, 1, 0);
116+}
117+
118+static inline void qdio_stop_polling(struct qdio_q *q)
119 {
120 if (!q->u.in.polling)
121 return;
122@@ -507,7 +513,7 @@ out:
123 return q->first_to_check;
124 }
125
126-int qdio_inbound_q_moved(struct qdio_q *q)
127+static int qdio_inbound_q_moved(struct qdio_q *q)
128 {
129 int bufnr;
130
131@@ -587,6 +593,22 @@ void qdio_kick_inbound_handler(struct qd
132 q->qdio_error = 0;
133 }
134
135+static inline int tiqdio_inbound_q_done(struct qdio_q *q)
136+{
137+ unsigned char state = 0;
138+
139+ if (!atomic_read(&q->nr_buf_used))
140+ return 1;
141+
142+ qdio_siga_sync_q(q);
143+ get_buf_state(q, q->first_to_check, &state, 0);
144+
145+ if (state == SLSB_P_INPUT_PRIMED)
146+ /* more work coming */
147+ return 0;
148+ return 1;
149+}
150+
151 static void __qdio_inbound_processing(struct qdio_q *q)
152 {
153 qdio_perf_stat_inc(&perf_stats.tasklet_inbound);
154@@ -609,7 +631,6 @@ again:
155 goto again;
156 }
157
158-/* inbound tasklet */
159 void qdio_inbound_processing(unsigned long data)
160 {
161 struct qdio_q *q = (struct qdio_q *)data;
162@@ -812,8 +833,7 @@ void qdio_outbound_timer(unsigned long d
163 tasklet_schedule(&q->tasklet);
164 }
165
166-/* called from thinint inbound tasklet */
167-void qdio_check_outbound_after_thinint(struct qdio_q *q)
168+static inline void qdio_check_outbound_after_thinint(struct qdio_q *q)
169 {
170 struct qdio_q *out;
171 int i;
172@@ -826,6 +846,47 @@ void qdio_check_outbound_after_thinint(s
173 tasklet_schedule(&out->tasklet);
174 }
175
176+static void __tiqdio_inbound_processing(struct qdio_q *q)
177+{
178+ qdio_perf_stat_inc(&perf_stats.thinint_inbound);
179+ qdio_sync_after_thinint(q);
180+
181+ /*
182+ * The interrupt could be caused by a PCI request. Check the
183+ * PCI capable outbound queues.
184+ */
185+ qdio_check_outbound_after_thinint(q);
186+
187+ if (!qdio_inbound_q_moved(q))
188+ return;
189+
190+ qdio_kick_inbound_handler(q);
191+
192+ if (!tiqdio_inbound_q_done(q)) {
193+ qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop);
194+ if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
195+ tasklet_schedule(&q->tasklet);
196+ return;
197+ }
198+
199+ qdio_stop_polling(q);
200+ /*
201+ * We need to check again to not lose initiative after
202+ * resetting the ACK state.
203+ */
204+ if (!tiqdio_inbound_q_done(q)) {
205+ qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2);
206+ if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
207+ tasklet_schedule(&q->tasklet);
208+ }
209+}
210+
211+void tiqdio_inbound_processing(unsigned long data)
212+{
213+ struct qdio_q *q = (struct qdio_q *)data;
214+ __tiqdio_inbound_processing(q);
215+}
216+
217 static inline void qdio_set_state(struct qdio_irq *irq_ptr,
218 enum qdio_irq_states state)
219 {
220Index: linux-sles11/drivers/s390/cio/qdio_thinint.c
221===================================================================
222--- linux-sles11.orig/drivers/s390/cio/qdio_thinint.c
223+++ linux-sles11/drivers/s390/cio/qdio_thinint.c
224@@ -126,68 +126,11 @@ void tiqdio_remove_input_queues(struct q
225 }
226 }
227
228-static inline int tiqdio_inbound_q_done(struct qdio_q *q)
229-{
230- unsigned char state;
231-
232- if (!atomic_read(&q->nr_buf_used))
233- return 1;
234-
235- qdio_siga_sync_q(q);
236- get_buf_state(q, q->first_to_check, &state, 0);
237-
238- if (state == SLSB_P_INPUT_PRIMED)
239- /* more work coming */
240- return 0;
241- return 1;
242-}
243-
244 static inline int shared_ind(struct qdio_irq *irq_ptr)
245 {
246 return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
247 }
248
249-static void __tiqdio_inbound_processing(struct qdio_q *q)
250-{
251- qdio_perf_stat_inc(&perf_stats.thinint_inbound);
252- qdio_sync_after_thinint(q);
253-
254- /*
255- * Maybe we have work on our outbound queues... at least
256- * we have to check the PCI capable queues.
257- */
258- qdio_check_outbound_after_thinint(q);
259-
260- if (!qdio_inbound_q_moved(q))
261- return;
262-
263- qdio_kick_inbound_handler(q);
264-
265- if (!tiqdio_inbound_q_done(q)) {
266- qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop);
267- if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
268- tasklet_schedule(&q->tasklet);
269- }
270-
271- qdio_stop_polling(q);
272- /*
273- * We need to check again to not lose initiative after
274- * resetting the ACK state.
275- */
276- if (!tiqdio_inbound_q_done(q)) {
277- qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2);
278- if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
279- tasklet_schedule(&q->tasklet);
280- }
281-}
282-
283-void tiqdio_inbound_processing(unsigned long data)
284-{
285- struct qdio_q *q = (struct qdio_q *)data;
286-
287- __tiqdio_inbound_processing(q);
288-}
289-
290 /* check for work on all inbound thinint queues */
291 static void tiqdio_tasklet_fn(unsigned long data)
292 {