diff options
author | Cliff Wickman <cpw@sgi.com> | 2011-05-24 14:07:36 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-05-25 08:20:14 -0400 |
commit | f073cc8f39b48fdf4c8cd9520a6028fe69199b60 (patch) | |
tree | 7ab21c251ce91794d429d82aed68a675bb4b5263 /arch/x86/include/asm/uv/uv_bau.h | |
parent | 2a919596c16b4333af851ff473ebf96e289ab90c (diff) |
x86, UV: Clean up uv_tlb.c
SGI UV's uv_tlb.c driver has become rather hard to read, with overly large
functions, non-standard coding style and (way) too long variable, constant
and function names and non-obvious code flow sequences.
This patch improves the readability and maintainability of the driver
significantly, by doing the following strict code cleanups with no side
effects:
- Split long functions into shorter logical functions.
- Shortened some variable and structure member names.
- Added special functions for reads and writes of MMR regs with
very long names.
- Added the 'tunables' table to shortened tunables_write().
- Added the 'stat_description' table to shorten uv_ptc_proc_write().
- Pass fewer 'stat' arguments where it can be derived from the 'bcp'
argument.
- Function definitions consistent on one line, and inline in few (short) cases.
- Moved some small structures and an atomic inline function to the header file.
- Moved some local variables to the blocks where they are used.
- Updated the copyright date.
- Shortened uv_write_global_mmr64() etc. using some aliasing; no
line breaks. Renamed many uv_.. functions that are not exported.
- Aligned structure fields.
[ note that not all structures are aligned the same way though; I'd like
to keep the extensive commenting in some of them. ]
- Shortened some long structure names.
- Standard pass/fail exit from init_per_cpu()
- Vertical alignment for mass initializations.
- More separation between blocks of code.
Tested on a 16-processor Altix UV.
Signed-off-by: Cliff Wickman <cpw@sgi.com>
Cc: penberg@kernel.org
Link: http://lkml.kernel.org/r/E1QOw12-0004MN-Lp@eag09.americas.sgi.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/include/asm/uv/uv_bau.h')
-rw-r--r-- | arch/x86/include/asm/uv/uv_bau.h | 554 |
1 files changed, 351 insertions, 203 deletions
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index 0652a5a9fd6..a291c40efd4 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * SGI UV Broadcast Assist Unit definitions | 6 | * SGI UV Broadcast Assist Unit definitions |
7 | * | 7 | * |
8 | * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved. | 8 | * Copyright (C) 2008-2011 Silicon Graphics, Inc. All rights reserved. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifndef _ASM_X86_UV_UV_BAU_H | 11 | #ifndef _ASM_X86_UV_UV_BAU_H |
@@ -35,9 +35,9 @@ | |||
35 | 35 | ||
36 | #define MAX_CPUS_PER_UVHUB 64 | 36 | #define MAX_CPUS_PER_UVHUB 64 |
37 | #define MAX_CPUS_PER_SOCKET 32 | 37 | #define MAX_CPUS_PER_SOCKET 32 |
38 | #define UV_ADP_SIZE 64 /* hardware-provided max. */ | 38 | #define ADP_SZ 64 /* hardware-provided max. */ |
39 | #define UV_CPUS_PER_ACT_STATUS 32 /* hardware-provided max. */ | 39 | #define UV_CPUS_PER_AS 32 /* hardware-provided max. */ |
40 | #define UV_ITEMS_PER_DESCRIPTOR 8 | 40 | #define ITEMS_PER_DESC 8 |
41 | /* the 'throttle' to prevent the hardware stay-busy bug */ | 41 | /* the 'throttle' to prevent the hardware stay-busy bug */ |
42 | #define MAX_BAU_CONCURRENT 3 | 42 | #define MAX_BAU_CONCURRENT 3 |
43 | #define UV_ACT_STATUS_MASK 0x3 | 43 | #define UV_ACT_STATUS_MASK 0x3 |
@@ -48,7 +48,7 @@ | |||
48 | #define UV2_NET_ENDPOINT_INTD 0x28 | 48 | #define UV2_NET_ENDPOINT_INTD 0x28 |
49 | #define UV_NET_ENDPOINT_INTD (is_uv1_hub() ? \ | 49 | #define UV_NET_ENDPOINT_INTD (is_uv1_hub() ? \ |
50 | UV1_NET_ENDPOINT_INTD : UV2_NET_ENDPOINT_INTD) | 50 | UV1_NET_ENDPOINT_INTD : UV2_NET_ENDPOINT_INTD) |
51 | #define UV_DESC_BASE_PNODE_SHIFT 49 | 51 | #define UV_DESC_PSHIFT 49 |
52 | #define UV_PAYLOADQ_PNODE_SHIFT 49 | 52 | #define UV_PAYLOADQ_PNODE_SHIFT 49 |
53 | #define UV_PTC_BASENAME "sgi_uv/ptc_statistics" | 53 | #define UV_PTC_BASENAME "sgi_uv/ptc_statistics" |
54 | #define UV_BAU_BASENAME "sgi_uv/bau_tunables" | 54 | #define UV_BAU_BASENAME "sgi_uv/bau_tunables" |
@@ -56,7 +56,8 @@ | |||
56 | #define UV_BAU_TUNABLES_FILE "bau_tunables" | 56 | #define UV_BAU_TUNABLES_FILE "bau_tunables" |
57 | #define WHITESPACE " \t\n" | 57 | #define WHITESPACE " \t\n" |
58 | #define uv_physnodeaddr(x) ((__pa((unsigned long)(x)) & uv_mmask)) | 58 | #define uv_physnodeaddr(x) ((__pa((unsigned long)(x)) & uv_mmask)) |
59 | 59 | #define cpubit_isset(cpu, bau_local_cpumask) \ | |
60 | test_bit((cpu), (bau_local_cpumask).bits) | ||
60 | 61 | ||
61 | /* [19:16] SOFT_ACK timeout period 19: 1 is urgency 7 17:16 1 is multiplier */ | 62 | /* [19:16] SOFT_ACK timeout period 19: 1 is urgency 7 17:16 1 is multiplier */ |
62 | /* | 63 | /* |
@@ -72,25 +73,37 @@ | |||
72 | UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD : \ | 73 | UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD : \ |
73 | UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD) | 74 | UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD) |
74 | 75 | ||
75 | #define BAU_MISC_CONTROL_MULT_MASK 3 | 76 | #define BAU_MISC_CONTROL_MULT_MASK 3 |
76 | 77 | ||
77 | #define UVH_AGING_PRESCALE_SEL 0x000000b000UL | 78 | #define UVH_AGING_PRESCALE_SEL 0x000000b000UL |
78 | /* [30:28] URGENCY_7 an index into a table of times */ | 79 | /* [30:28] URGENCY_7 an index into a table of times */ |
79 | #define BAU_URGENCY_7_SHIFT 28 | 80 | #define BAU_URGENCY_7_SHIFT 28 |
80 | #define BAU_URGENCY_7_MASK 7 | 81 | #define BAU_URGENCY_7_MASK 7 |
81 | 82 | ||
82 | #define UVH_TRANSACTION_TIMEOUT 0x000000b200UL | 83 | #define UVH_TRANSACTION_TIMEOUT 0x000000b200UL |
83 | /* [45:40] BAU - BAU transaction timeout select - a multiplier */ | 84 | /* [45:40] BAU - BAU transaction timeout select - a multiplier */ |
84 | #define BAU_TRANS_SHIFT 40 | 85 | #define BAU_TRANS_SHIFT 40 |
85 | #define BAU_TRANS_MASK 0x3f | 86 | #define BAU_TRANS_MASK 0x3f |
87 | |||
88 | /* | ||
89 | * shorten some awkward names | ||
90 | */ | ||
91 | #define AS_PUSH_SHIFT UVH_LB_BAU_SB_ACTIVATION_CONTROL_PUSH_SHFT | ||
92 | #define SOFTACK_MSHIFT UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT | ||
93 | #define SOFTACK_PSHIFT UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT | ||
94 | #define SOFTACK_TIMEOUT_PERIOD UV_INTD_SOFT_ACK_TIMEOUT_PERIOD | ||
95 | #define write_gmmr uv_write_global_mmr64 | ||
96 | #define write_lmmr uv_write_local_mmr | ||
97 | #define read_lmmr uv_read_local_mmr | ||
98 | #define read_gmmr uv_read_global_mmr64 | ||
86 | 99 | ||
87 | /* | 100 | /* |
88 | * bits in UVH_LB_BAU_SB_ACTIVATION_STATUS_0/1 | 101 | * bits in UVH_LB_BAU_SB_ACTIVATION_STATUS_0/1 |
89 | */ | 102 | */ |
90 | #define DESC_STATUS_IDLE 0 | 103 | #define DS_IDLE 0 |
91 | #define DESC_STATUS_ACTIVE 1 | 104 | #define DS_ACTIVE 1 |
92 | #define DESC_STATUS_DESTINATION_TIMEOUT 2 | 105 | #define DS_DESTINATION_TIMEOUT 2 |
93 | #define DESC_STATUS_SOURCE_TIMEOUT 3 | 106 | #define DS_SOURCE_TIMEOUT 3 |
94 | /* | 107 | /* |
95 | * bits put together from HRP_LB_BAU_SB_ACTIVATION_STATUS_0/1/2 | 108 | * bits put together from HRP_LB_BAU_SB_ACTIVATION_STATUS_0/1/2 |
96 | * values 1 and 5 will not occur | 109 | * values 1 and 5 will not occur |
@@ -111,22 +124,22 @@ | |||
111 | * threshholds at which to use IPI to free resources | 124 | * threshholds at which to use IPI to free resources |
112 | */ | 125 | */ |
113 | /* after this # consecutive 'plugged' timeouts, use IPI to release resources */ | 126 | /* after this # consecutive 'plugged' timeouts, use IPI to release resources */ |
114 | #define PLUGSB4RESET 100 | 127 | #define PLUGSB4RESET 100 |
115 | /* after this many consecutive timeouts, use IPI to release resources */ | 128 | /* after this many consecutive timeouts, use IPI to release resources */ |
116 | #define TIMEOUTSB4RESET 1 | 129 | #define TIMEOUTSB4RESET 1 |
117 | /* at this number uses of IPI to release resources, giveup the request */ | 130 | /* at this number uses of IPI to release resources, giveup the request */ |
118 | #define IPI_RESET_LIMIT 1 | 131 | #define IPI_RESET_LIMIT 1 |
119 | /* after this # consecutive successes, bump up the throttle if it was lowered */ | 132 | /* after this # consecutive successes, bump up the throttle if it was lowered */ |
120 | #define COMPLETE_THRESHOLD 5 | 133 | #define COMPLETE_THRESHOLD 5 |
121 | 134 | ||
122 | #define UV_LB_SUBNODEID 0x10 | 135 | #define UV_LB_SUBNODEID 0x10 |
123 | 136 | ||
124 | /* these two are the same for UV1 and UV2: */ | 137 | /* these two are the same for UV1 and UV2: */ |
125 | #define UV_SA_SHFT UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT | 138 | #define UV_SA_SHFT UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT |
126 | #define UV_SA_MASK UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK | 139 | #define UV_SA_MASK UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK |
127 | /* 4 bits of software ack period */ | 140 | /* 4 bits of software ack period */ |
128 | #define UV2_ACK_MASK 0x7UL | 141 | #define UV2_ACK_MASK 0x7UL |
129 | #define UV2_ACK_UNITS_SHFT 3 | 142 | #define UV2_ACK_UNITS_SHFT 3 |
130 | #define UV2_LEG_SHFT UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT | 143 | #define UV2_LEG_SHFT UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT |
131 | #define UV2_EXT_SHFT UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT | 144 | #define UV2_EXT_SHFT UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT |
132 | 145 | ||
@@ -149,9 +162,16 @@ | |||
149 | /* | 162 | /* |
150 | * tuning the action when the numalink network is extremely delayed | 163 | * tuning the action when the numalink network is extremely delayed |
151 | */ | 164 | */ |
152 | #define CONGESTED_RESPONSE_US 1000 /* 'long' response time, in microseconds */ | 165 | #define CONGESTED_RESPONSE_US 1000 /* 'long' response time, in |
153 | #define CONGESTED_REPS 10 /* long delays averaged over this many broadcasts */ | 166 | microseconds */ |
154 | #define CONGESTED_PERIOD 30 /* time for the bau to be disabled, in seconds */ | 167 | #define CONGESTED_REPS 10 /* long delays averaged over |
168 | this many broadcasts */ | ||
169 | #define CONGESTED_PERIOD 30 /* time for the bau to be | ||
170 | disabled, in seconds */ | ||
171 | /* see msg_type: */ | ||
172 | #define MSG_NOOP 0 | ||
173 | #define MSG_REGULAR 1 | ||
174 | #define MSG_RETRY 2 | ||
155 | 175 | ||
156 | /* | 176 | /* |
157 | * Distribution: 32 bytes (256 bits) (bytes 0-0x1f of descriptor) | 177 | * Distribution: 32 bytes (256 bits) (bytes 0-0x1f of descriptor) |
@@ -163,8 +183,8 @@ | |||
163 | * 'base_dest_nasid' field of the header corresponds to the | 183 | * 'base_dest_nasid' field of the header corresponds to the |
164 | * destination nodeID associated with that specified bit. | 184 | * destination nodeID associated with that specified bit. |
165 | */ | 185 | */ |
166 | struct bau_target_uvhubmask { | 186 | struct bau_targ_hubmask { |
167 | unsigned long bits[BITS_TO_LONGS(UV_DISTRIBUTION_SIZE)]; | 187 | unsigned long bits[BITS_TO_LONGS(UV_DISTRIBUTION_SIZE)]; |
168 | }; | 188 | }; |
169 | 189 | ||
170 | /* | 190 | /* |
@@ -173,7 +193,7 @@ struct bau_target_uvhubmask { | |||
173 | * enough bits for max. cpu's per uvhub) | 193 | * enough bits for max. cpu's per uvhub) |
174 | */ | 194 | */ |
175 | struct bau_local_cpumask { | 195 | struct bau_local_cpumask { |
176 | unsigned long bits; | 196 | unsigned long bits; |
177 | }; | 197 | }; |
178 | 198 | ||
179 | /* | 199 | /* |
@@ -194,14 +214,14 @@ struct bau_local_cpumask { | |||
194 | * The payload is software-defined for INTD transactions | 214 | * The payload is software-defined for INTD transactions |
195 | */ | 215 | */ |
196 | struct bau_msg_payload { | 216 | struct bau_msg_payload { |
197 | unsigned long address; /* signifies a page or all TLB's | 217 | unsigned long address; /* signifies a page or all |
198 | of the cpu */ | 218 | TLB's of the cpu */ |
199 | /* 64 bits */ | 219 | /* 64 bits */ |
200 | unsigned short sending_cpu; /* filled in by sender */ | 220 | unsigned short sending_cpu; /* filled in by sender */ |
201 | /* 16 bits */ | 221 | /* 16 bits */ |
202 | unsigned short acknowledge_count;/* filled in by destination */ | 222 | unsigned short acknowledge_count; /* filled in by destination */ |
203 | /* 16 bits */ | 223 | /* 16 bits */ |
204 | unsigned int reserved1:32; /* not usable */ | 224 | unsigned int reserved1:32; /* not usable */ |
205 | }; | 225 | }; |
206 | 226 | ||
207 | 227 | ||
@@ -210,93 +230,96 @@ struct bau_msg_payload { | |||
210 | * see table 4.2.3.0.1 in broacast_assist spec. | 230 | * see table 4.2.3.0.1 in broacast_assist spec. |
211 | */ | 231 | */ |
212 | struct bau_msg_header { | 232 | struct bau_msg_header { |
213 | unsigned int dest_subnodeid:6; /* must be 0x10, for the LB */ | 233 | unsigned int dest_subnodeid:6; /* must be 0x10, for the LB */ |
214 | /* bits 5:0 */ | 234 | /* bits 5:0 */ |
215 | unsigned int base_dest_nasid:15; /* nasid of the */ | 235 | unsigned int base_dest_nasid:15; /* nasid of the first bit */ |
216 | /* bits 20:6 */ /* first bit in uvhub map */ | 236 | /* bits 20:6 */ /* in uvhub map */ |
217 | unsigned int command:8; /* message type */ | 237 | unsigned int command:8; /* message type */ |
218 | /* bits 28:21 */ | 238 | /* bits 28:21 */ |
219 | /* 0x38: SN3net EndPoint Message */ | 239 | /* 0x38: SN3net EndPoint Message */ |
220 | unsigned int rsvd_1:3; /* must be zero */ | 240 | unsigned int rsvd_1:3; /* must be zero */ |
221 | /* bits 31:29 */ | 241 | /* bits 31:29 */ |
222 | /* int will align on 32 bits */ | 242 | /* int will align on 32 bits */ |
223 | unsigned int rsvd_2:9; /* must be zero */ | 243 | unsigned int rsvd_2:9; /* must be zero */ |
224 | /* bits 40:32 */ | 244 | /* bits 40:32 */ |
225 | /* Suppl_A is 56-41 */ | 245 | /* Suppl_A is 56-41 */ |
226 | unsigned int sequence:16;/* message sequence number */ | 246 | unsigned int sequence:16; /* message sequence number */ |
227 | /* bits 56:41 */ /* becomes bytes 16-17 of msg */ | 247 | /* bits 56:41 */ /* becomes bytes 16-17 of msg */ |
228 | /* Address field (96:57) is never used as an | 248 | /* Address field (96:57) is |
229 | address (these are address bits 42:3) */ | 249 | never used as an address |
230 | 250 | (these are address bits | |
231 | unsigned int rsvd_3:1; /* must be zero */ | 251 | 42:3) */ |
252 | |||
253 | unsigned int rsvd_3:1; /* must be zero */ | ||
232 | /* bit 57 */ | 254 | /* bit 57 */ |
233 | /* address bits 27:4 are payload */ | 255 | /* address bits 27:4 are payload */ |
234 | /* these next 24 (58-81) bits become bytes 12-14 of msg */ | 256 | /* these next 24 (58-81) bits become bytes 12-14 of msg */ |
235 | |||
236 | /* bits 65:58 land in byte 12 */ | 257 | /* bits 65:58 land in byte 12 */ |
237 | unsigned int replied_to:1;/* sent as 0 by the source to byte 12 */ | 258 | unsigned int replied_to:1; /* sent as 0 by the source to |
259 | byte 12 */ | ||
238 | /* bit 58 */ | 260 | /* bit 58 */ |
239 | unsigned int msg_type:3; /* software type of the message*/ | 261 | unsigned int msg_type:3; /* software type of the |
262 | message */ | ||
240 | /* bits 61:59 */ | 263 | /* bits 61:59 */ |
241 | unsigned int canceled:1; /* message canceled, resource to be freed*/ | 264 | unsigned int canceled:1; /* message canceled, resource |
265 | is to be freed*/ | ||
242 | /* bit 62 */ | 266 | /* bit 62 */ |
243 | unsigned int payload_1a:1;/* not currently used */ | 267 | unsigned int payload_1a:1; /* not currently used */ |
244 | /* bit 63 */ | 268 | /* bit 63 */ |
245 | unsigned int payload_1b:2;/* not currently used */ | 269 | unsigned int payload_1b:2; /* not currently used */ |
246 | /* bits 65:64 */ | 270 | /* bits 65:64 */ |
247 | 271 | ||
248 | /* bits 73:66 land in byte 13 */ | 272 | /* bits 73:66 land in byte 13 */ |
249 | unsigned int payload_1ca:6;/* not currently used */ | 273 | unsigned int payload_1ca:6; /* not currently used */ |
250 | /* bits 71:66 */ | 274 | /* bits 71:66 */ |
251 | unsigned int payload_1c:2;/* not currently used */ | 275 | unsigned int payload_1c:2; /* not currently used */ |
252 | /* bits 73:72 */ | 276 | /* bits 73:72 */ |
253 | 277 | ||
254 | /* bits 81:74 land in byte 14 */ | 278 | /* bits 81:74 land in byte 14 */ |
255 | unsigned int payload_1d:6;/* not currently used */ | 279 | unsigned int payload_1d:6; /* not currently used */ |
256 | /* bits 79:74 */ | 280 | /* bits 79:74 */ |
257 | unsigned int payload_1e:2;/* not currently used */ | 281 | unsigned int payload_1e:2; /* not currently used */ |
258 | /* bits 81:80 */ | 282 | /* bits 81:80 */ |
259 | 283 | ||
260 | unsigned int rsvd_4:7; /* must be zero */ | 284 | unsigned int rsvd_4:7; /* must be zero */ |
261 | /* bits 88:82 */ | 285 | /* bits 88:82 */ |
262 | unsigned int sw_ack_flag:1;/* software acknowledge flag */ | 286 | unsigned int swack_flag:1; /* software acknowledge flag */ |
263 | /* bit 89 */ | 287 | /* bit 89 */ |
264 | /* INTD trasactions at destination are to | 288 | /* INTD trasactions at |
265 | wait for software acknowledge */ | 289 | destination are to wait for |
266 | unsigned int rsvd_5:6; /* must be zero */ | 290 | software acknowledge */ |
291 | unsigned int rsvd_5:6; /* must be zero */ | ||
267 | /* bits 95:90 */ | 292 | /* bits 95:90 */ |
268 | unsigned int rsvd_6:5; /* must be zero */ | 293 | unsigned int rsvd_6:5; /* must be zero */ |
269 | /* bits 100:96 */ | 294 | /* bits 100:96 */ |
270 | unsigned int int_both:1;/* if 1, interrupt both sockets on the uvhub */ | 295 | unsigned int int_both:1; /* if 1, interrupt both sockets |
296 | on the uvhub */ | ||
271 | /* bit 101*/ | 297 | /* bit 101*/ |
272 | unsigned int fairness:3;/* usually zero */ | 298 | unsigned int fairness:3; /* usually zero */ |
273 | /* bits 104:102 */ | 299 | /* bits 104:102 */ |
274 | unsigned int multilevel:1; /* multi-level multicast format */ | 300 | unsigned int multilevel:1; /* multi-level multicast |
301 | format */ | ||
275 | /* bit 105 */ | 302 | /* bit 105 */ |
276 | /* 0 for TLB: endpoint multi-unicast messages */ | 303 | /* 0 for TLB: endpoint multi-unicast messages */ |
277 | unsigned int chaining:1;/* next descriptor is part of this activation*/ | 304 | unsigned int chaining:1; /* next descriptor is part of |
305 | this activation*/ | ||
278 | /* bit 106 */ | 306 | /* bit 106 */ |
279 | unsigned int rsvd_7:21; /* must be zero */ | 307 | unsigned int rsvd_7:21; /* must be zero */ |
280 | /* bits 127:107 */ | 308 | /* bits 127:107 */ |
281 | }; | 309 | }; |
282 | 310 | ||
283 | /* see msg_type: */ | ||
284 | #define MSG_NOOP 0 | ||
285 | #define MSG_REGULAR 1 | ||
286 | #define MSG_RETRY 2 | ||
287 | |||
288 | /* | 311 | /* |
289 | * The activation descriptor: | 312 | * The activation descriptor: |
290 | * The format of the message to send, plus all accompanying control | 313 | * The format of the message to send, plus all accompanying control |
291 | * Should be 64 bytes | 314 | * Should be 64 bytes |
292 | */ | 315 | */ |
293 | struct bau_desc { | 316 | struct bau_desc { |
294 | struct bau_target_uvhubmask distribution; | 317 | struct bau_targ_hubmask distribution; |
295 | /* | 318 | /* |
296 | * message template, consisting of header and payload: | 319 | * message template, consisting of header and payload: |
297 | */ | 320 | */ |
298 | struct bau_msg_header header; | 321 | struct bau_msg_header header; |
299 | struct bau_msg_payload payload; | 322 | struct bau_msg_payload payload; |
300 | }; | 323 | }; |
301 | /* | 324 | /* |
302 | * -payload-- ---------header------ | 325 | * -payload-- ---------header------ |
@@ -315,59 +338,51 @@ struct bau_desc { | |||
315 | * are 32 bytes (2 micropackets) (256 bits) in length, but contain only 17 | 338 | * are 32 bytes (2 micropackets) (256 bits) in length, but contain only 17 |
316 | * bytes of usable data, including the sw ack vector in byte 15 (bits 127:120) | 339 | * bytes of usable data, including the sw ack vector in byte 15 (bits 127:120) |
317 | * (12 bytes come from bau_msg_payload, 3 from payload_1, 2 from | 340 | * (12 bytes come from bau_msg_payload, 3 from payload_1, 2 from |
318 | * sw_ack_vector and payload_2) | 341 | * swack_vec and payload_2) |
319 | * "Enabling Software Acknowledgment mode (see Section 4.3.3 Software | 342 | * "Enabling Software Acknowledgment mode (see Section 4.3.3 Software |
320 | * Acknowledge Processing) also selects 32 byte (17 bytes usable) payload | 343 | * Acknowledge Processing) also selects 32 byte (17 bytes usable) payload |
321 | * operation." | 344 | * operation." |
322 | */ | 345 | */ |
323 | struct bau_payload_queue_entry { | 346 | struct bau_pq_entry { |
324 | unsigned long address; /* signifies a page or all TLB's | 347 | unsigned long address; /* signifies a page or all TLB's |
325 | of the cpu */ | 348 | of the cpu */ |
326 | /* 64 bits, bytes 0-7 */ | 349 | /* 64 bits, bytes 0-7 */ |
327 | 350 | unsigned short sending_cpu; /* cpu that sent the message */ | |
328 | unsigned short sending_cpu; /* cpu that sent the message */ | ||
329 | /* 16 bits, bytes 8-9 */ | 351 | /* 16 bits, bytes 8-9 */ |
330 | 352 | unsigned short acknowledge_count; /* filled in by destination */ | |
331 | unsigned short acknowledge_count; /* filled in by destination */ | ||
332 | /* 16 bits, bytes 10-11 */ | 353 | /* 16 bits, bytes 10-11 */ |
333 | |||
334 | /* these next 3 bytes come from bits 58-81 of the message header */ | 354 | /* these next 3 bytes come from bits 58-81 of the message header */ |
335 | unsigned short replied_to:1; /* sent as 0 by the source */ | 355 | unsigned short replied_to:1; /* sent as 0 by the source */ |
336 | unsigned short msg_type:3; /* software message type */ | 356 | unsigned short msg_type:3; /* software message type */ |
337 | unsigned short canceled:1; /* sent as 0 by the source */ | 357 | unsigned short canceled:1; /* sent as 0 by the source */ |
338 | unsigned short unused1:3; /* not currently using */ | 358 | unsigned short unused1:3; /* not currently using */ |
339 | /* byte 12 */ | 359 | /* byte 12 */ |
340 | 360 | unsigned char unused2a; /* not currently using */ | |
341 | unsigned char unused2a; /* not currently using */ | ||
342 | /* byte 13 */ | 361 | /* byte 13 */ |
343 | unsigned char unused2; /* not currently using */ | 362 | unsigned char unused2; /* not currently using */ |
344 | /* byte 14 */ | 363 | /* byte 14 */ |
345 | 364 | unsigned char swack_vec; /* filled in by the hardware */ | |
346 | unsigned char sw_ack_vector; /* filled in by the hardware */ | ||
347 | /* byte 15 (bits 127:120) */ | 365 | /* byte 15 (bits 127:120) */ |
348 | 366 | unsigned short sequence; /* message sequence number */ | |
349 | unsigned short sequence; /* message sequence number */ | ||
350 | /* bytes 16-17 */ | 367 | /* bytes 16-17 */ |
351 | unsigned char unused4[2]; /* not currently using bytes 18-19 */ | 368 | unsigned char unused4[2]; /* not currently using bytes 18-19 */ |
352 | /* bytes 18-19 */ | 369 | /* bytes 18-19 */ |
353 | 370 | int number_of_cpus; /* filled in at destination */ | |
354 | int number_of_cpus; /* filled in at destination */ | ||
355 | /* 32 bits, bytes 20-23 (aligned) */ | 371 | /* 32 bits, bytes 20-23 (aligned) */ |
356 | 372 | unsigned char unused5[8]; /* not using */ | |
357 | unsigned char unused5[8]; /* not using */ | ||
358 | /* bytes 24-31 */ | 373 | /* bytes 24-31 */ |
359 | }; | 374 | }; |
360 | 375 | ||
361 | struct msg_desc { | 376 | struct msg_desc { |
362 | struct bau_payload_queue_entry *msg; | 377 | struct bau_pq_entry *msg; |
363 | int msg_slot; | 378 | int msg_slot; |
364 | int sw_ack_slot; | 379 | int swack_slot; |
365 | struct bau_payload_queue_entry *va_queue_first; | 380 | struct bau_pq_entry *queue_first; |
366 | struct bau_payload_queue_entry *va_queue_last; | 381 | struct bau_pq_entry *queue_last; |
367 | }; | 382 | }; |
368 | 383 | ||
369 | struct reset_args { | 384 | struct reset_args { |
370 | int sender; | 385 | int sender; |
371 | }; | 386 | }; |
372 | 387 | ||
373 | /* | 388 | /* |
@@ -375,112 +390,226 @@ struct reset_args { | |||
375 | */ | 390 | */ |
376 | struct ptc_stats { | 391 | struct ptc_stats { |
377 | /* sender statistics */ | 392 | /* sender statistics */ |
378 | unsigned long s_giveup; /* number of fall backs to IPI-style flushes */ | 393 | unsigned long s_giveup; /* number of fall backs to |
379 | unsigned long s_requestor; /* number of shootdown requests */ | 394 | IPI-style flushes */ |
380 | unsigned long s_stimeout; /* source side timeouts */ | 395 | unsigned long s_requestor; /* number of shootdown |
381 | unsigned long s_dtimeout; /* destination side timeouts */ | 396 | requests */ |
382 | unsigned long s_time; /* time spent in sending side */ | 397 | unsigned long s_stimeout; /* source side timeouts */ |
383 | unsigned long s_retriesok; /* successful retries */ | 398 | unsigned long s_dtimeout; /* destination side timeouts */ |
384 | unsigned long s_ntargcpu; /* total number of cpu's targeted */ | 399 | unsigned long s_time; /* time spent in sending side */ |
385 | unsigned long s_ntargself; /* times the sending cpu was targeted */ | 400 | unsigned long s_retriesok; /* successful retries */ |
386 | unsigned long s_ntarglocals; /* targets of cpus on the local blade */ | 401 | unsigned long s_ntargcpu; /* total number of cpu's |
387 | unsigned long s_ntargremotes; /* targets of cpus on remote blades */ | 402 | targeted */ |
388 | unsigned long s_ntarglocaluvhub; /* targets of the local hub */ | 403 | unsigned long s_ntargself; /* times the sending cpu was |
389 | unsigned long s_ntargremoteuvhub; /* remotes hubs targeted */ | 404 | targeted */ |
390 | unsigned long s_ntarguvhub; /* total number of uvhubs targeted */ | 405 | unsigned long s_ntarglocals; /* targets of cpus on the local |
391 | unsigned long s_ntarguvhub16; /* number of times target hubs >= 16*/ | 406 | blade */ |
392 | unsigned long s_ntarguvhub8; /* number of times target hubs >= 8 */ | 407 | unsigned long s_ntargremotes; /* targets of cpus on remote |
393 | unsigned long s_ntarguvhub4; /* number of times target hubs >= 4 */ | 408 | blades */ |
394 | unsigned long s_ntarguvhub2; /* number of times target hubs >= 2 */ | 409 | unsigned long s_ntarglocaluvhub; /* targets of the local hub */ |
395 | unsigned long s_ntarguvhub1; /* number of times target hubs == 1 */ | 410 | unsigned long s_ntargremoteuvhub; /* remotes hubs targeted */ |
396 | unsigned long s_resets_plug; /* ipi-style resets from plug state */ | 411 | unsigned long s_ntarguvhub; /* total number of uvhubs |
397 | unsigned long s_resets_timeout; /* ipi-style resets from timeouts */ | 412 | targeted */ |
398 | unsigned long s_busy; /* status stayed busy past s/w timer */ | 413 | unsigned long s_ntarguvhub16; /* number of times target |
399 | unsigned long s_throttles; /* waits in throttle */ | 414 | hubs >= 16*/ |
400 | unsigned long s_retry_messages; /* retry broadcasts */ | 415 | unsigned long s_ntarguvhub8; /* number of times target |
401 | unsigned long s_bau_reenabled; /* for bau enable/disable */ | 416 | hubs >= 8 */ |
402 | unsigned long s_bau_disabled; /* for bau enable/disable */ | 417 | unsigned long s_ntarguvhub4; /* number of times target |
418 | hubs >= 4 */ | ||
419 | unsigned long s_ntarguvhub2; /* number of times target | ||
420 | hubs >= 2 */ | ||
421 | unsigned long s_ntarguvhub1; /* number of times target | ||
422 | hubs == 1 */ | ||
423 | unsigned long s_resets_plug; /* ipi-style resets from plug | ||
424 | state */ | ||
425 | unsigned long s_resets_timeout; /* ipi-style resets from | ||
426 | timeouts */ | ||
427 | unsigned long s_busy; /* status stayed busy past | ||
428 | s/w timer */ | ||
429 | unsigned long s_throttles; /* waits in throttle */ | ||
430 | unsigned long s_retry_messages; /* retry broadcasts */ | ||
431 | unsigned long s_bau_reenabled; /* for bau enable/disable */ | ||
432 | unsigned long s_bau_disabled; /* for bau enable/disable */ | ||
403 | /* destination statistics */ | 433 | /* destination statistics */ |
404 | unsigned long d_alltlb; /* times all tlb's on this cpu were flushed */ | 434 | unsigned long d_alltlb; /* times all tlb's on this |
405 | unsigned long d_onetlb; /* times just one tlb on this cpu was flushed */ | 435 | cpu were flushed */ |
406 | unsigned long d_multmsg; /* interrupts with multiple messages */ | 436 | unsigned long d_onetlb; /* times just one tlb on this |
407 | unsigned long d_nomsg; /* interrupts with no message */ | 437 | cpu was flushed */ |
408 | unsigned long d_time; /* time spent on destination side */ | 438 | unsigned long d_multmsg; /* interrupts with multiple |
409 | unsigned long d_requestee; /* number of messages processed */ | 439 | messages */ |
410 | unsigned long d_retries; /* number of retry messages processed */ | 440 | unsigned long d_nomsg; /* interrupts with no message */ |
411 | unsigned long d_canceled; /* number of messages canceled by retries */ | 441 | unsigned long d_time; /* time spent on destination |
412 | unsigned long d_nocanceled; /* retries that found nothing to cancel */ | 442 | side */ |
413 | unsigned long d_resets; /* number of ipi-style requests processed */ | 443 | unsigned long d_requestee; /* number of messages |
414 | unsigned long d_rcanceled; /* number of messages canceled by resets */ | 444 | processed */ |
445 | unsigned long d_retries; /* number of retry messages | ||
446 | processed */ | ||
447 | unsigned long d_canceled; /* number of messages canceled | ||
448 | by retries */ | ||
449 | unsigned long d_nocanceled; /* retries that found nothing | ||
450 | to cancel */ | ||
451 | unsigned long d_resets; /* number of ipi-style requests | ||
452 | processed */ | ||
453 | unsigned long d_rcanceled; /* number of messages canceled | ||
454 | by resets */ | ||
455 | }; | ||
456 | |||
457 | struct tunables { | ||
458 | int *tunp; | ||
459 | int deflt; | ||
415 | }; | 460 | }; |
416 | 461 | ||
417 | struct hub_and_pnode { | 462 | struct hub_and_pnode { |
418 | short uvhub; | 463 | short uvhub; |
419 | short pnode; | 464 | short pnode; |
465 | }; | ||
466 | |||
467 | struct socket_desc { | ||
468 | short num_cpus; | ||
469 | short cpu_number[MAX_CPUS_PER_SOCKET]; | ||
470 | }; | ||
471 | |||
472 | struct uvhub_desc { | ||
473 | unsigned short socket_mask; | ||
474 | short num_cpus; | ||
475 | short uvhub; | ||
476 | short pnode; | ||
477 | struct socket_desc socket[2]; | ||
420 | }; | 478 | }; |
479 | |||
421 | /* | 480 | /* |
422 | * one per-cpu; to locate the software tables | 481 | * one per-cpu; to locate the software tables |
423 | */ | 482 | */ |
424 | struct bau_control { | 483 | struct bau_control { |
425 | struct bau_desc *descriptor_base; | 484 | struct bau_desc *descriptor_base; |
426 | struct bau_payload_queue_entry *va_queue_first; | 485 | struct bau_pq_entry *queue_first; |
427 | struct bau_payload_queue_entry *va_queue_last; | 486 | struct bau_pq_entry *queue_last; |
428 | struct bau_payload_queue_entry *bau_msg_head; | 487 | struct bau_pq_entry *bau_msg_head; |
429 | struct bau_control *uvhub_master; | 488 | struct bau_control *uvhub_master; |
430 | struct bau_control *socket_master; | 489 | struct bau_control *socket_master; |
431 | struct ptc_stats *statp; | 490 | struct ptc_stats *statp; |
432 | unsigned long timeout_interval; | 491 | unsigned long timeout_interval; |
433 | unsigned long set_bau_on_time; | 492 | unsigned long set_bau_on_time; |
434 | atomic_t active_descriptor_count; | 493 | atomic_t active_descriptor_count; |
435 | int plugged_tries; | 494 | int plugged_tries; |
436 | int timeout_tries; | 495 | int timeout_tries; |
437 | int ipi_attempts; | 496 | int ipi_attempts; |
438 | int conseccompletes; | 497 | int conseccompletes; |
439 | int baudisabled; | 498 | int baudisabled; |
440 | int set_bau_off; | 499 | int set_bau_off; |
441 | short cpu; | 500 | short cpu; |
442 | short osnode; | 501 | short osnode; |
443 | short uvhub_cpu; | 502 | short uvhub_cpu; |
444 | short uvhub; | 503 | short uvhub; |
445 | short cpus_in_socket; | 504 | short cpus_in_socket; |
446 | short cpus_in_uvhub; | 505 | short cpus_in_uvhub; |
447 | short partition_base_pnode; | 506 | short partition_base_pnode; |
448 | unsigned short message_number; | 507 | unsigned short message_number; |
449 | unsigned short uvhub_quiesce; | 508 | unsigned short uvhub_quiesce; |
450 | short socket_acknowledge_count[DEST_Q_SIZE]; | 509 | short socket_acknowledge_count[DEST_Q_SIZE]; |
451 | cycles_t send_message; | 510 | cycles_t send_message; |
452 | spinlock_t uvhub_lock; | 511 | spinlock_t uvhub_lock; |
453 | spinlock_t queue_lock; | 512 | spinlock_t queue_lock; |
454 | /* tunables */ | 513 | /* tunables */ |
455 | int max_bau_concurrent; | 514 | int max_concurr; |
456 | int max_bau_concurrent_constant; | 515 | int max_concurr_const; |
457 | int plugged_delay; | 516 | int plugged_delay; |
458 | int plugsb4reset; | 517 | int plugsb4reset; |
459 | int timeoutsb4reset; | 518 | int timeoutsb4reset; |
460 | int ipi_reset_limit; | 519 | int ipi_reset_limit; |
461 | int complete_threshold; | 520 | int complete_threshold; |
462 | int congested_response_us; | 521 | int cong_response_us; |
463 | int congested_reps; | 522 | int cong_reps; |
464 | int congested_period; | 523 | int cong_period; |
465 | cycles_t period_time; | 524 | cycles_t period_time; |
466 | long period_requests; | 525 | long period_requests; |
467 | struct hub_and_pnode *target_hub_and_pnode; | 526 | struct hub_and_pnode *thp; |
468 | }; | 527 | }; |
469 | 528 | ||
470 | static inline int bau_uvhub_isset(int uvhub, struct bau_target_uvhubmask *dstp) | 529 | static unsigned long read_mmr_uv2_status(void) |
530 | { | ||
531 | return read_lmmr(UV2H_LB_BAU_SB_ACTIVATION_STATUS_2); | ||
532 | } | ||
533 | |||
534 | static void write_mmr_data_broadcast(int pnode, unsigned long mmr_image) | ||
535 | { | ||
536 | write_gmmr(pnode, UVH_BAU_DATA_BROADCAST, mmr_image); | ||
537 | } | ||
538 | |||
539 | static void write_mmr_descriptor_base(int pnode, unsigned long mmr_image) | ||
540 | { | ||
541 | write_gmmr(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE, mmr_image); | ||
542 | } | ||
543 | |||
544 | static void write_mmr_activation(unsigned long index) | ||
545 | { | ||
546 | write_lmmr(UVH_LB_BAU_SB_ACTIVATION_CONTROL, index); | ||
547 | } | ||
548 | |||
549 | static void write_gmmr_activation(int pnode, unsigned long mmr_image) | ||
550 | { | ||
551 | write_gmmr(pnode, UVH_LB_BAU_SB_ACTIVATION_CONTROL, mmr_image); | ||
552 | } | ||
553 | |||
554 | static void write_mmr_payload_first(int pnode, unsigned long mmr_image) | ||
555 | { | ||
556 | write_gmmr(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST, mmr_image); | ||
557 | } | ||
558 | |||
559 | static void write_mmr_payload_tail(int pnode, unsigned long mmr_image) | ||
560 | { | ||
561 | write_gmmr(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL, mmr_image); | ||
562 | } | ||
563 | |||
564 | static void write_mmr_payload_last(int pnode, unsigned long mmr_image) | ||
565 | { | ||
566 | write_gmmr(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST, mmr_image); | ||
567 | } | ||
568 | |||
569 | static void write_mmr_misc_control(int pnode, unsigned long mmr_image) | ||
570 | { | ||
571 | write_gmmr(pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image); | ||
572 | } | ||
573 | |||
574 | static unsigned long read_mmr_misc_control(int pnode) | ||
575 | { | ||
576 | return read_gmmr(pnode, UVH_LB_BAU_MISC_CONTROL); | ||
577 | } | ||
578 | |||
579 | static void write_mmr_sw_ack(unsigned long mr) | ||
580 | { | ||
581 | uv_write_local_mmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, mr); | ||
582 | } | ||
583 | |||
584 | static unsigned long read_mmr_sw_ack(void) | ||
585 | { | ||
586 | return read_lmmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE); | ||
587 | } | ||
588 | |||
589 | static unsigned long read_gmmr_sw_ack(int pnode) | ||
590 | { | ||
591 | return read_gmmr(pnode, UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE); | ||
592 | } | ||
593 | |||
594 | static void write_mmr_data_config(int pnode, unsigned long mr) | ||
595 | { | ||
596 | uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG, mr); | ||
597 | } | ||
598 | |||
599 | static inline int bau_uvhub_isset(int uvhub, struct bau_targ_hubmask *dstp) | ||
471 | { | 600 | { |
472 | return constant_test_bit(uvhub, &dstp->bits[0]); | 601 | return constant_test_bit(uvhub, &dstp->bits[0]); |
473 | } | 602 | } |
474 | static inline void bau_uvhub_set(int pnode, struct bau_target_uvhubmask *dstp) | 603 | static inline void bau_uvhub_set(int pnode, struct bau_targ_hubmask *dstp) |
475 | { | 604 | { |
476 | __set_bit(pnode, &dstp->bits[0]); | 605 | __set_bit(pnode, &dstp->bits[0]); |
477 | } | 606 | } |
478 | static inline void bau_uvhubs_clear(struct bau_target_uvhubmask *dstp, | 607 | static inline void bau_uvhubs_clear(struct bau_targ_hubmask *dstp, |
479 | int nbits) | 608 | int nbits) |
480 | { | 609 | { |
481 | bitmap_zero(&dstp->bits[0], nbits); | 610 | bitmap_zero(&dstp->bits[0], nbits); |
482 | } | 611 | } |
483 | static inline int bau_uvhub_weight(struct bau_target_uvhubmask *dstp) | 612 | static inline int bau_uvhub_weight(struct bau_targ_hubmask *dstp) |
484 | { | 613 | { |
485 | return bitmap_weight((unsigned long *)&dstp->bits[0], | 614 | return bitmap_weight((unsigned long *)&dstp->bits[0], |
486 | UV_DISTRIBUTION_SIZE); | 615 | UV_DISTRIBUTION_SIZE); |
@@ -491,9 +620,6 @@ static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits) | |||
491 | bitmap_zero(&dstp->bits, nbits); | 620 | bitmap_zero(&dstp->bits, nbits); |
492 | } | 621 | } |
493 | 622 | ||
494 | #define cpubit_isset(cpu, bau_local_cpumask) \ | ||
495 | test_bit((cpu), (bau_local_cpumask).bits) | ||
496 | |||
497 | extern void uv_bau_message_intr1(void); | 623 | extern void uv_bau_message_intr1(void); |
498 | extern void uv_bau_timeout_intr1(void); | 624 | extern void uv_bau_timeout_intr1(void); |
499 | 625 | ||
@@ -501,7 +627,7 @@ struct atomic_short { | |||
501 | short counter; | 627 | short counter; |
502 | }; | 628 | }; |
503 | 629 | ||
504 | /** | 630 | /* |
505 | * atomic_read_short - read a short atomic variable | 631 | * atomic_read_short - read a short atomic variable |
506 | * @v: pointer of type atomic_short | 632 | * @v: pointer of type atomic_short |
507 | * | 633 | * |
@@ -512,14 +638,14 @@ static inline int atomic_read_short(const struct atomic_short *v) | |||
512 | return v->counter; | 638 | return v->counter; |
513 | } | 639 | } |
514 | 640 | ||
515 | /** | 641 | /* |
516 | * atomic_add_short_return - add and return a short int | 642 | * atom_asr - add and return a short int |
517 | * @i: short value to add | 643 | * @i: short value to add |
518 | * @v: pointer of type atomic_short | 644 | * @v: pointer of type atomic_short |
519 | * | 645 | * |
520 | * Atomically adds @i to @v and returns @i + @v | 646 | * Atomically adds @i to @v and returns @i + @v |
521 | */ | 647 | */ |
522 | static inline int atomic_add_short_return(short i, struct atomic_short *v) | 648 | static inline int atom_asr(short i, struct atomic_short *v) |
523 | { | 649 | { |
524 | short __i = i; | 650 | short __i = i; |
525 | asm volatile(LOCK_PREFIX "xaddw %0, %1" | 651 | asm volatile(LOCK_PREFIX "xaddw %0, %1" |
@@ -528,4 +654,26 @@ static inline int atomic_add_short_return(short i, struct atomic_short *v) | |||
528 | return i + __i; | 654 | return i + __i; |
529 | } | 655 | } |
530 | 656 | ||
657 | /* | ||
658 | * conditionally add 1 to *v, unless *v is >= u | ||
659 | * return 0 if we cannot add 1 to *v because it is >= u | ||
660 | * return 1 if we can add 1 to *v because it is < u | ||
661 | * the add is atomic | ||
662 | * | ||
663 | * This is close to atomic_add_unless(), but this allows the 'u' value | ||
664 | * to be lowered below the current 'v'. atomic_add_unless can only stop | ||
665 | * on equal. | ||
666 | */ | ||
667 | static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u) | ||
668 | { | ||
669 | spin_lock(lock); | ||
670 | if (atomic_read(v) >= u) { | ||
671 | spin_unlock(lock); | ||
672 | return 0; | ||
673 | } | ||
674 | atomic_inc(v); | ||
675 | spin_unlock(lock); | ||
676 | return 1; | ||
677 | } | ||
678 | |||
531 | #endif /* _ASM_X86_UV_UV_BAU_H */ | 679 | #endif /* _ASM_X86_UV_UV_BAU_H */ |