]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.arch/s390-11-09-qdio_ack_newest_and_seperate_polling.patch
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.arch / s390-11-09-qdio_ack_newest_and_seperate_polling.patch
1 From: Gerald Schaefer <geraldsc@de.ibm.com>
2 Subject: qdio: move ACK to newest buffer for devices without QEBSM
3 References: bnc#484767,LTC#52208
4
5 Symptom: Lower performance of non-QEBSM qdio devices under heavy traffic
6 Problem: The ACKnowledgement state is set on the first SBAL so in case of
7 multiple PRIMED buffers the firmware has to scan all buffers.
8 Solution: The ACKnowledgement state is set on the newest SBAL so an
9 adapter interrupt surpression check needs to scan fewer SBALs.
10
11 Acked-by: John Jolly <jjolly@suse.de>
12 ---
13 drivers/s390/cio/qdio.h | 5 ++++-
14 drivers/s390/cio/qdio_debug.c | 3 ++-
15 drivers/s390/cio/qdio_main.c | 41 ++++++++++++++++++++---------------------
16 3 files changed, 26 insertions(+), 23 deletions(-)
17
18 Index: linux-sles11/drivers/s390/cio/qdio.h
19 ===================================================================
20 --- linux-sles11.orig/drivers/s390/cio/qdio.h
21 +++ linux-sles11/drivers/s390/cio/qdio.h
22 @@ -186,6 +186,9 @@ struct qdio_input_q {
23 /* input buffer acknowledgement flag */
24 int polling;
25
26 + /* first ACK'ed buffer */
27 + int ack_start;
28 +
29 /* how much sbals are acknowledged with qebsm */
30 int ack_count;
31
32 @@ -231,7 +234,7 @@ struct qdio_q {
33 int first_to_check;
34
35 /* first_to_check of the last time */
36 - int last_move_ftc;
37 + int last_move;
38
39 /* beginning position for calling the program */
40 int first_to_kick;
41 Index: linux-sles11/drivers/s390/cio/qdio_debug.c
42 ===================================================================
43 --- linux-sles11.orig/drivers/s390/cio/qdio_debug.c
44 +++ linux-sles11/drivers/s390/cio/qdio_debug.c
45 @@ -62,8 +62,9 @@ static int qstat_show(struct seq_file *m
46 seq_printf(m, "device state indicator: %d\n", *(u32 *)q->irq_ptr->dsci);
47 seq_printf(m, "nr_used: %d\n", atomic_read(&q->nr_buf_used));
48 seq_printf(m, "ftc: %d\n", q->first_to_check);
49 - seq_printf(m, "last_move_ftc: %d\n", q->last_move_ftc);
50 + seq_printf(m, "last_move: %d\n", q->last_move);
51 seq_printf(m, "polling: %d\n", q->u.in.polling);
52 + seq_printf(m, "ack start: %d\n", q->u.in.ack_start);
53 seq_printf(m, "ack count: %d\n", q->u.in.ack_count);
54 seq_printf(m, "slsb buffer states:\n");
55 seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n");
56 Index: linux-sles11/drivers/s390/cio/qdio_main.c
57 ===================================================================
58 --- linux-sles11.orig/drivers/s390/cio/qdio_main.c
59 +++ linux-sles11/drivers/s390/cio/qdio_main.c
60 @@ -371,11 +371,11 @@ inline void qdio_stop_polling(struct qdi
61
62 /* show the card that we are not polling anymore */
63 if (is_qebsm(q)) {
64 - set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT,
65 + set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
66 q->u.in.ack_count);
67 q->u.in.ack_count = 0;
68 } else
69 - set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT);
70 + set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
71 }
72
73 static void announce_buffer_error(struct qdio_q *q, int count)
74 @@ -410,15 +410,15 @@ static inline void inbound_primed(struct
75 if (!q->u.in.polling) {
76 q->u.in.polling = 1;
77 q->u.in.ack_count = count;
78 - q->last_move_ftc = q->first_to_check;
79 + q->u.in.ack_start = q->first_to_check;
80 return;
81 }
82
83 /* delete the previous ACK's */
84 - set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT,
85 + set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
86 q->u.in.ack_count);
87 q->u.in.ack_count = count;
88 - q->last_move_ftc = q->first_to_check;
89 + q->u.in.ack_start = q->first_to_check;
90 return;
91 }
92
93 @@ -430,14 +430,13 @@ static inline void inbound_primed(struct
94 if (q->u.in.polling) {
95 /* reset the previous ACK but first set the new one */
96 set_buf_state(q, new, SLSB_P_INPUT_ACK);
97 - set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT);
98 - }
99 - else {
100 + set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
101 + } else {
102 q->u.in.polling = 1;
103 - set_buf_state(q, q->first_to_check, SLSB_P_INPUT_ACK);
104 + set_buf_state(q, new, SLSB_P_INPUT_ACK);
105 }
106
107 - q->last_move_ftc = new;
108 + q->u.in.ack_start = new;
109 count--;
110 if (!count)
111 return;
112 @@ -446,7 +445,7 @@ static inline void inbound_primed(struct
113 * Need to change all PRIMED buffers to NOT_INIT, otherwise
114 * we're loosing initiative in the thinint code.
115 */
116 - set_buf_states(q, next_buf(q->first_to_check), SLSB_P_INPUT_NOT_INIT,
117 + set_buf_states(q, q->first_to_check, SLSB_P_INPUT_NOT_INIT,
118 count);
119 }
120
121 @@ -514,7 +513,8 @@ int qdio_inbound_q_moved(struct qdio_q *
122
123 bufnr = get_inbound_buffer_frontier(q);
124
125 - if ((bufnr != q->last_move_ftc) || q->qdio_error) {
126 + if ((bufnr != q->last_move) || q->qdio_error) {
127 + q->last_move = bufnr;
128 if (!need_siga_sync(q) && !pci_out_supported(q))
129 q->u.in.timestamp = get_usecs();
130
131 @@ -689,8 +689,8 @@ static inline int qdio_outbound_q_moved(
132
133 bufnr = get_outbound_buffer_frontier(q);
134
135 - if ((bufnr != q->last_move_ftc) || q->qdio_error) {
136 - q->last_move_ftc = bufnr;
137 + if ((bufnr != q->last_move) || q->qdio_error) {
138 + q->last_move = bufnr;
139 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr);
140 return 1;
141 } else
142 @@ -732,7 +732,7 @@ static void qdio_kick_outbound_handler(s
143 int start, end, count;
144
145 start = q->first_to_kick;
146 - end = q->last_move_ftc;
147 + end = q->last_move;
148 if (end >= start)
149 count = end - start;
150 else
151 @@ -748,7 +748,7 @@ static void qdio_kick_outbound_handler(s
152 q->irq_ptr->int_parm);
153
154 /* for the next time: */
155 - q->first_to_kick = q->last_move_ftc;
156 + q->first_to_kick = q->last_move;
157 q->qdio_error = 0;
158 }
159
160 @@ -1453,19 +1453,18 @@ static int handle_inbound(struct qdio_q
161 q->u.in.polling = 0;
162 q->u.in.ack_count = 0;
163 goto set;
164 - } else if (buf_in_between(q->last_move_ftc, bufnr, count)) {
165 + } else if (buf_in_between(q->u.in.ack_start, bufnr, count)) {
166 if (is_qebsm(q)) {
167 - /* partial overwrite, just update last_move_ftc */
168 + /* partial overwrite, just update ack_start */
169 diff = add_buf(bufnr, count);
170 - diff = sub_buf(diff, q->last_move_ftc);
171 + diff = sub_buf(diff, q->u.in.ack_start);
172 q->u.in.ack_count -= diff;
173 if (q->u.in.ack_count <= 0) {
174 q->u.in.polling = 0;
175 q->u.in.ack_count = 0;
176 - /* TODO: must we set last_move_ftc to something meaningful? */
177 goto set;
178 }
179 - q->last_move_ftc = add_buf(q->last_move_ftc, diff);
180 + q->u.in.ack_start = add_buf(q->u.in.ack_start, diff);
181 }
182 else
183 /* the only ACK will be deleted, so stop polling */