diff options
| -rw-r--r-- | arch/x86/include/asm/uv/uv_bau.h | 12 | ||||
| -rw-r--r-- | arch/x86/kernel/tlb_uv.c | 51 |
2 files changed, 59 insertions, 4 deletions
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index aa558ac0306e..458e04c626a2 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h | |||
| @@ -49,6 +49,18 @@ | |||
| 49 | #define UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT 15 | 49 | #define UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT 15 |
| 50 | #define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT 16 | 50 | #define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT 16 |
| 51 | #define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x000000000bUL | 51 | #define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x000000000bUL |
| 52 | /* [19:16] SOFT_ACK timeout period 19: 1 is urgency 7 17:16 1 is multiplier */ | ||
| 53 | #define BAU_MISC_CONTROL_MULT_MASK 3 | ||
| 54 | |||
| 55 | #define UVH_AGING_PRESCALE_SEL 0x000000b000UL | ||
| 56 | /* [30:28] URGENCY_7 an index into a table of times */ | ||
| 57 | #define BAU_URGENCY_7_SHIFT 28 | ||
| 58 | #define BAU_URGENCY_7_MASK 7 | ||
| 59 | |||
| 60 | #define UVH_TRANSACTION_TIMEOUT 0x000000b200UL | ||
| 61 | /* [45:40] BAU - BAU transaction timeout select - a multiplier */ | ||
| 62 | #define BAU_TRANS_SHIFT 40 | ||
| 63 | #define BAU_TRANS_MASK 0x3f | ||
| 52 | 64 | ||
| 53 | /* | 65 | /* |
| 54 | * bits in UVH_LB_BAU_SB_ACTIVATION_STATUS_0/1 | 66 | * bits in UVH_LB_BAU_SB_ACTIVATION_STATUS_0/1 |
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c index 7fea555929e2..5506836c4a82 100644 --- a/arch/x86/kernel/tlb_uv.c +++ b/arch/x86/kernel/tlb_uv.c | |||
| @@ -30,6 +30,19 @@ struct msg_desc { | |||
| 30 | struct bau_payload_queue_entry *va_queue_last; | 30 | struct bau_payload_queue_entry *va_queue_last; |
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | /* timeouts in nanoseconds (indexed by UVH_AGING_PRESCALE_SEL urgency7 30:28) */ | ||
| 34 | static int timeout_base_ns[] = { | ||
| 35 | 20, | ||
| 36 | 160, | ||
| 37 | 1280, | ||
| 38 | 10240, | ||
| 39 | 81920, | ||
| 40 | 655360, | ||
| 41 | 5242880, | ||
| 42 | 167772160 | ||
| 43 | }; | ||
| 44 | static int timeout_us; | ||
| 45 | |||
| 33 | #define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x000000000bUL | 46 | #define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x000000000bUL |
| 34 | 47 | ||
| 35 | static int uv_bau_max_concurrent __read_mostly; | 48 | static int uv_bau_max_concurrent __read_mostly; |
| @@ -423,7 +436,8 @@ static int uv_wait_completion(struct bau_desc *bau_desc, | |||
| 423 | * pending. In that case hardware returns the | 436 | * pending. In that case hardware returns the |
| 424 | * ERROR that looks like a destination timeout. | 437 | * ERROR that looks like a destination timeout. |
| 425 | */ | 438 | */ |
| 426 | if (cycles_2_us(ttime - bcp->send_message) < BIOS_TO) { | 439 | if (cycles_2_us(ttime - bcp->send_message) < |
| 440 | timeout_us) { | ||
| 427 | bcp->conseccompletes = 0; | 441 | bcp->conseccompletes = 0; |
| 428 | return FLUSH_RETRY_PLUGGED; | 442 | return FLUSH_RETRY_PLUGGED; |
| 429 | } | 443 | } |
| @@ -908,12 +922,12 @@ static void uv_ptc_seq_stop(struct seq_file *file, void *data) | |||
| 908 | } | 922 | } |
| 909 | 923 | ||
| 910 | static inline unsigned long long | 924 | static inline unsigned long long |
| 911 | millisec_2_cycles(unsigned long millisec) | 925 | microsec_2_cycles(unsigned long microsec) |
| 912 | { | 926 | { |
| 913 | unsigned long ns; | 927 | unsigned long ns; |
| 914 | unsigned long long cyc; | 928 | unsigned long long cyc; |
| 915 | 929 | ||
| 916 | ns = millisec * 1000; | 930 | ns = microsec * 1000; |
| 917 | cyc = (ns << CYC2NS_SCALE_FACTOR)/(per_cpu(cyc2ns, smp_processor_id())); | 931 | cyc = (ns << CYC2NS_SCALE_FACTOR)/(per_cpu(cyc2ns, smp_processor_id())); |
| 918 | return cyc; | 932 | return cyc; |
| 919 | } | 933 | } |
| @@ -1259,6 +1273,33 @@ static void __init uv_init_uvhub(int uvhub, int vector) | |||
| 1259 | } | 1273 | } |
| 1260 | 1274 | ||
| 1261 | /* | 1275 | /* |
| 1276 | * We will set BAU_MISC_CONTROL with a timeout period. | ||
| 1277 | * But the BIOS has set UVH_AGING_PRESCALE_SEL and UVH_TRANSACTION_TIMEOUT. | ||
| 1278 | * So the destination timeout period has be be calculated from them. | ||
| 1279 | */ | ||
| 1280 | static int | ||
| 1281 | calculate_destination_timeout(void) | ||
| 1282 | { | ||
| 1283 | unsigned long mmr_image; | ||
| 1284 | int mult1; | ||
| 1285 | int mult2; | ||
| 1286 | int index; | ||
| 1287 | int base; | ||
| 1288 | int ret; | ||
| 1289 | unsigned long ts_ns; | ||
| 1290 | |||
| 1291 | mult1 = UV_INTD_SOFT_ACK_TIMEOUT_PERIOD & BAU_MISC_CONTROL_MULT_MASK; | ||
| 1292 | mmr_image = uv_read_local_mmr(UVH_AGING_PRESCALE_SEL); | ||
| 1293 | index = (mmr_image >> BAU_URGENCY_7_SHIFT) & BAU_URGENCY_7_MASK; | ||
| 1294 | mmr_image = uv_read_local_mmr(UVH_TRANSACTION_TIMEOUT); | ||
| 1295 | mult2 = (mmr_image >> BAU_TRANS_SHIFT) & BAU_TRANS_MASK; | ||
| 1296 | base = timeout_base_ns[index]; | ||
| 1297 | ts_ns = base * mult1 * mult2; | ||
| 1298 | ret = ts_ns / 1000; | ||
| 1299 | return ret; | ||
| 1300 | } | ||
| 1301 | |||
| 1302 | /* | ||
| 1262 | * initialize the bau_control structure for each cpu | 1303 | * initialize the bau_control structure for each cpu |
| 1263 | */ | 1304 | */ |
| 1264 | static void uv_init_per_cpu(int nuvhubs) | 1305 | static void uv_init_per_cpu(int nuvhubs) |
| @@ -1286,6 +1327,8 @@ static void uv_init_per_cpu(int nuvhubs) | |||
| 1286 | }; | 1327 | }; |
| 1287 | struct uvhub_desc *uvhub_descs; | 1328 | struct uvhub_desc *uvhub_descs; |
| 1288 | 1329 | ||
| 1330 | timeout_us = calculate_destination_timeout(); | ||
| 1331 | |||
| 1289 | uvhub_descs = (struct uvhub_desc *) | 1332 | uvhub_descs = (struct uvhub_desc *) |
| 1290 | kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); | 1333 | kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); |
| 1291 | memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc)); | 1334 | memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc)); |
| @@ -1301,7 +1344,7 @@ static void uv_init_per_cpu(int nuvhubs) | |||
| 1301 | bdp->uvhub = uvhub; | 1344 | bdp->uvhub = uvhub; |
| 1302 | bdp->pnode = pnode; | 1345 | bdp->pnode = pnode; |
| 1303 | /* time interval to catch a hardware stay-busy bug */ | 1346 | /* time interval to catch a hardware stay-busy bug */ |
| 1304 | bcp->timeout_interval = millisec_2_cycles(3); | 1347 | bcp->timeout_interval = microsec_2_cycles(2*timeout_us); |
| 1305 | /* kludge: assume uv_hub.h is constant */ | 1348 | /* kludge: assume uv_hub.h is constant */ |
| 1306 | socket = (cpu_physical_id(cpu)>>5)&1; | 1349 | socket = (cpu_physical_id(cpu)>>5)&1; |
| 1307 | if (socket >= bdp->num_sockets) | 1350 | if (socket >= bdp->num_sockets) |
