]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.39/patches.arch/s390-17-perf-04-qdio_move_adapter_interrupt_tasklet_code.patch
Imported linux-2.6.27.39 suse/xen patches.
[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
1 From: Gerald Schaefer <geraldsc@de.ibm.com>
2 Subject: [PATCH] qdio: move adapter interrupt tasklet code
3 References: bnc#532063,LTC#55526
4
5 From: Jan Glauber <jang@linux.vnet.ibm.com>
6
7 Move the adapter interrupt tasklet function to the qdio main code
8 since all the functions used by the tasklet are located there.
9
10 Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
11
12 Acked-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
21 Index: 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 */
48 Index: 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:
63 Index: 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 {
220 Index: 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 {