Skip to content

Commit 5637a2a

Browse files
committed
Merge branch 'x86-uv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 UV TLB update from Ingo Molnar: "UV TLB shootdown logic updates for version of the UV architecture" * 'x86-uv-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/uv: Update the UV3 TLB shootdown logic
2 parents d782ceb + a26fd71 commit 5637a2a

File tree

2 files changed

+49
-39
lines changed

2 files changed

+49
-39
lines changed

arch/x86/include/asm/uv/uv_bau.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD (is_uv1_hub() ? \
7474
UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD : \
7575
UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD)
76+
/* assuming UV3 is the same */
7677

7778
#define BAU_MISC_CONTROL_MULT_MASK 3
7879

@@ -93,6 +94,8 @@
9394
#define SOFTACK_MSHIFT UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT
9495
#define SOFTACK_PSHIFT UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT
9596
#define SOFTACK_TIMEOUT_PERIOD UV_INTD_SOFT_ACK_TIMEOUT_PERIOD
97+
#define PREFETCH_HINT_SHFT UV3H_LB_BAU_MISC_CONTROL_ENABLE_INTD_PREFETCH_HINT_SHFT
98+
#define SB_STATUS_SHFT UV3H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT
9699
#define write_gmmr uv_write_global_mmr64
97100
#define write_lmmr uv_write_local_mmr
98101
#define read_lmmr uv_read_local_mmr
@@ -322,8 +325,9 @@ struct uv1_bau_msg_header {
322325
/*
323326
* UV2 Message header: 16 bytes (128 bits) (bytes 0x30-0x3f of descriptor)
324327
* see figure 9-2 of harp_sys.pdf
328+
* assuming UV3 is the same
325329
*/
326-
struct uv2_bau_msg_header {
330+
struct uv2_3_bau_msg_header {
327331
unsigned int base_dest_nasid:15; /* nasid of the first bit */
328332
/* bits 14:0 */ /* in uvhub map */
329333
unsigned int dest_subnodeid:5; /* must be 0x10, for the LB */
@@ -395,7 +399,7 @@ struct bau_desc {
395399
*/
396400
union bau_msg_header {
397401
struct uv1_bau_msg_header uv1_hdr;
398-
struct uv2_bau_msg_header uv2_hdr;
402+
struct uv2_3_bau_msg_header uv2_3_hdr;
399403
} header;
400404

401405
struct bau_msg_payload payload;
@@ -631,11 +635,6 @@ struct bau_control {
631635
struct hub_and_pnode *thp;
632636
};
633637

634-
static inline unsigned long read_mmr_uv2_status(void)
635-
{
636-
return read_lmmr(UV2H_LB_BAU_SB_ACTIVATION_STATUS_2);
637-
}
638-
639638
static inline void write_mmr_data_broadcast(int pnode, unsigned long mmr_image)
640639
{
641640
write_gmmr(pnode, UVH_BAU_DATA_BROADCAST, mmr_image);
@@ -760,7 +759,11 @@ static inline int atomic_read_short(const struct atomic_short *v)
760759
*/
761760
static inline int atom_asr(short i, struct atomic_short *v)
762761
{
763-
return i + xadd(&v->counter, i);
762+
short __i = i;
763+
asm volatile(LOCK_PREFIX "xaddw %0, %1"
764+
: "+r" (i), "+m" (v->counter)
765+
: : "memory");
766+
return i + __i;
764767
}
765768

766769
/*

arch/x86/platform/uv/tlb_uv.c

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* SGI UltraViolet TLB flush routines.
33
*
4-
* (c) 2008-2012 Cliff Wickman <[email protected]>, SGI.
4+
* (c) 2008-2014 Cliff Wickman <[email protected]>, SGI.
55
*
66
* This code is released under the GNU General Public License version 2 or
77
* later.
@@ -451,7 +451,7 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
451451

452452
/*
453453
* The reverse of the above; converts a duration in ns to a duration in cycles.
454-
*/
454+
*/
455455
static inline unsigned long long ns_2_cycles(unsigned long long ns)
456456
{
457457
struct cyc2ns_data *data = cyc2ns_read_begin();
@@ -563,7 +563,7 @@ static int uv1_wait_completion(struct bau_desc *bau_desc,
563563
* UV2 could have an extra bit of status in the ACTIVATION_STATUS_2 register.
564564
* But not currently used.
565565
*/
566-
static unsigned long uv2_read_status(unsigned long offset, int rshft, int desc)
566+
static unsigned long uv2_3_read_status(unsigned long offset, int rshft, int desc)
567567
{
568568
unsigned long descriptor_status;
569569

@@ -606,7 +606,7 @@ int handle_uv2_busy(struct bau_control *bcp)
606606
return FLUSH_GIVEUP;
607607
}
608608

609-
static int uv2_wait_completion(struct bau_desc *bau_desc,
609+
static int uv2_3_wait_completion(struct bau_desc *bau_desc,
610610
unsigned long mmr_offset, int right_shift,
611611
struct bau_control *bcp, long try)
612612
{
@@ -616,7 +616,7 @@ static int uv2_wait_completion(struct bau_desc *bau_desc,
616616
long busy_reps = 0;
617617
struct ptc_stats *stat = bcp->statp;
618618

619-
descriptor_stat = uv2_read_status(mmr_offset, right_shift, desc);
619+
descriptor_stat = uv2_3_read_status(mmr_offset, right_shift, desc);
620620

621621
/* spin on the status MMR, waiting for it to go idle */
622622
while (descriptor_stat != UV2H_DESC_IDLE) {
@@ -658,17 +658,15 @@ static int uv2_wait_completion(struct bau_desc *bau_desc,
658658
/* not to hammer on the clock */
659659
busy_reps = 0;
660660
ttm = get_cycles();
661-
if ((ttm - bcp->send_message) >
662-
bcp->timeout_interval)
661+
if ((ttm - bcp->send_message) > bcp->timeout_interval)
663662
return handle_uv2_busy(bcp);
664663
}
665664
/*
666665
* descriptor_stat is still BUSY
667666
*/
668667
cpu_relax();
669668
}
670-
descriptor_stat = uv2_read_status(mmr_offset, right_shift,
671-
desc);
669+
descriptor_stat = uv2_3_read_status(mmr_offset, right_shift, desc);
672670
}
673671
bcp->conseccompletes++;
674672
return FLUSH_COMPLETE;
@@ -679,8 +677,7 @@ static int uv2_wait_completion(struct bau_desc *bau_desc,
679677
* which register to read and position in that register based on cpu in
680678
* current hub.
681679
*/
682-
static int wait_completion(struct bau_desc *bau_desc,
683-
struct bau_control *bcp, long try)
680+
static int wait_completion(struct bau_desc *bau_desc, struct bau_control *bcp, long try)
684681
{
685682
int right_shift;
686683
unsigned long mmr_offset;
@@ -695,11 +692,9 @@ static int wait_completion(struct bau_desc *bau_desc,
695692
}
696693

697694
if (bcp->uvhub_version == 1)
698-
return uv1_wait_completion(bau_desc, mmr_offset, right_shift,
699-
bcp, try);
695+
return uv1_wait_completion(bau_desc, mmr_offset, right_shift, bcp, try);
700696
else
701-
return uv2_wait_completion(bau_desc, mmr_offset, right_shift,
702-
bcp, try);
697+
return uv2_3_wait_completion(bau_desc, mmr_offset, right_shift, bcp, try);
703698
}
704699

705700
/*
@@ -888,7 +883,7 @@ int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp,
888883
struct ptc_stats *stat = bcp->statp;
889884
struct bau_control *hmaster = bcp->uvhub_master;
890885
struct uv1_bau_msg_header *uv1_hdr = NULL;
891-
struct uv2_bau_msg_header *uv2_hdr = NULL;
886+
struct uv2_3_bau_msg_header *uv2_3_hdr = NULL;
892887

893888
if (bcp->uvhub_version == 1) {
894889
uv1 = 1;
@@ -902,27 +897,28 @@ int uv_flush_send_and_wait(struct cpumask *flush_mask, struct bau_control *bcp,
902897
if (uv1)
903898
uv1_hdr = &bau_desc->header.uv1_hdr;
904899
else
905-
uv2_hdr = &bau_desc->header.uv2_hdr;
900+
/* uv2 and uv3 */
901+
uv2_3_hdr = &bau_desc->header.uv2_3_hdr;
906902

907903
do {
908904
if (try == 0) {
909905
if (uv1)
910906
uv1_hdr->msg_type = MSG_REGULAR;
911907
else
912-
uv2_hdr->msg_type = MSG_REGULAR;
908+
uv2_3_hdr->msg_type = MSG_REGULAR;
913909
seq_number = bcp->message_number++;
914910
} else {
915911
if (uv1)
916912
uv1_hdr->msg_type = MSG_RETRY;
917913
else
918-
uv2_hdr->msg_type = MSG_RETRY;
914+
uv2_3_hdr->msg_type = MSG_RETRY;
919915
stat->s_retry_messages++;
920916
}
921917

922918
if (uv1)
923919
uv1_hdr->sequence = seq_number;
924920
else
925-
uv2_hdr->sequence = seq_number;
921+
uv2_3_hdr->sequence = seq_number;
926922
index = (1UL << AS_PUSH_SHIFT) | bcp->uvhub_cpu;
927923
bcp->send_message = get_cycles();
928924

@@ -1080,8 +1076,10 @@ static int set_distrib_bits(struct cpumask *flush_mask, struct bau_control *bcp,
10801076
* done. The returned pointer is valid till preemption is re-enabled.
10811077
*/
10821078
const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
1083-
struct mm_struct *mm, unsigned long start,
1084-
unsigned long end, unsigned int cpu)
1079+
struct mm_struct *mm,
1080+
unsigned long start,
1081+
unsigned long end,
1082+
unsigned int cpu)
10851083
{
10861084
int locals = 0;
10871085
int remotes = 0;
@@ -1268,6 +1266,7 @@ void uv_bau_message_interrupt(struct pt_regs *regs)
12681266
if (bcp->uvhub_version == 2)
12691267
process_uv2_message(&msgdesc, bcp);
12701268
else
1269+
/* no error workaround for uv1 or uv3 */
12711270
bau_process_message(&msgdesc, bcp, 1);
12721271

12731272
msg++;
@@ -1325,8 +1324,12 @@ static void __init enable_timeouts(void)
13251324
*/
13261325
mmr_image |= (1L << SOFTACK_MSHIFT);
13271326
if (is_uv2_hub()) {
1327+
/* do not touch the legacy mode bit */
13281328
/* hw bug workaround; do not use extended status */
13291329
mmr_image &= ~(1L << UV2_EXT_SHFT);
1330+
} else if (is_uv3_hub()) {
1331+
mmr_image &= ~(1L << PREFETCH_HINT_SHFT);
1332+
mmr_image |= (1L << SB_STATUS_SHFT);
13301333
}
13311334
write_mmr_misc_control(pnode, mmr_image);
13321335
}
@@ -1692,7 +1695,7 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode)
16921695
struct bau_desc *bau_desc;
16931696
struct bau_desc *bd2;
16941697
struct uv1_bau_msg_header *uv1_hdr;
1695-
struct uv2_bau_msg_header *uv2_hdr;
1698+
struct uv2_3_bau_msg_header *uv2_3_hdr;
16961699
struct bau_control *bcp;
16971700

16981701
/*
@@ -1739,15 +1742,15 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode)
17391742
*/
17401743
} else {
17411744
/*
1742-
* BIOS uses legacy mode, but UV2 hardware always
1745+
* BIOS uses legacy mode, but uv2 and uv3 hardware always
17431746
* uses native mode for selective broadcasts.
17441747
*/
1745-
uv2_hdr = &bd2->header.uv2_hdr;
1746-
uv2_hdr->swack_flag = 1;
1747-
uv2_hdr->base_dest_nasid =
1748+
uv2_3_hdr = &bd2->header.uv2_3_hdr;
1749+
uv2_3_hdr->swack_flag = 1;
1750+
uv2_3_hdr->base_dest_nasid =
17481751
UV_PNODE_TO_NASID(base_pnode);
1749-
uv2_hdr->dest_subnodeid = UV_LB_SUBNODEID;
1750-
uv2_hdr->command = UV_NET_ENDPOINT_INTD;
1752+
uv2_3_hdr->dest_subnodeid = UV_LB_SUBNODEID;
1753+
uv2_3_hdr->command = UV_NET_ENDPOINT_INTD;
17511754
}
17521755
}
17531756
for_each_present_cpu(cpu) {
@@ -1858,6 +1861,7 @@ static int calculate_destination_timeout(void)
18581861
ts_ns *= (mult1 * mult2);
18591862
ret = ts_ns / 1000;
18601863
} else {
1864+
/* same destination timeout for uv2 and uv3 */
18611865
/* 4 bits 0/1 for 10/80us base, 3 bits of multiplier */
18621866
mmr_image = uv_read_local_mmr(UVH_LB_BAU_MISC_CONTROL);
18631867
mmr_image = (mmr_image & UV_SA_MASK) >> UV_SA_SHFT;
@@ -2012,8 +2016,10 @@ static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp,
20122016
bcp->uvhub_version = 1;
20132017
else if (is_uv2_hub())
20142018
bcp->uvhub_version = 2;
2019+
else if (is_uv3_hub())
2020+
bcp->uvhub_version = 3;
20152021
else {
2016-
printk(KERN_EMERG "uvhub version not 1 or 2\n");
2022+
printk(KERN_EMERG "uvhub version not 1, 2 or 3\n");
20172023
return 1;
20182024
}
20192025
bcp->uvhub_master = *hmasterp;
@@ -2138,9 +2144,10 @@ static int __init uv_bau_init(void)
21382144
}
21392145

21402146
vector = UV_BAU_MESSAGE;
2141-
for_each_possible_blade(uvhub)
2147+
for_each_possible_blade(uvhub) {
21422148
if (uv_blade_nr_possible_cpus(uvhub))
21432149
init_uvhub(uvhub, vector, uv_base_pnode);
2150+
}
21442151

21452152
alloc_intr_gate(vector, uv_bau_message_intr1);
21462153

0 commit comments

Comments
 (0)