]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.arch/s390-11-09-qdio_ack_newest_and_seperate_polling.patch
Revert "Move xen patchset to new version's subdir."
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.arch / s390-11-09-qdio_ack_newest_and_seperate_polling.patch
CommitLineData
00e5a55c
BS
1From: Gerald Schaefer <geraldsc@de.ibm.com>
2Subject: qdio: move ACK to newest buffer for devices without QEBSM
3References: bnc#484767,LTC#52208
4
5Symptom: Lower performance of non-QEBSM qdio devices under heavy traffic
6Problem: The ACKnowledgement state is set on the first SBAL so in case of
7 multiple PRIMED buffers the firmware has to scan all buffers.
8Solution: The ACKnowledgement state is set on the newest SBAL so an
9 adapter interrupt surpression check needs to scan fewer SBALs.
10
11Acked-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
18Index: 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;
41Index: 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");
56Index: 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 */