Commit 9167522e authored by David Mosberger's avatar David Mosberger

ia64: Fix spurious GAS dependency-violation (dv) warnings by taking

	advantage of two new GAS directives (.serialize.{data,instruction}).
parent 11199079
...@@ -574,6 +574,10 @@ GLOBAL_ENTRY(fsys_bubble_down) ...@@ -574,6 +574,10 @@ GLOBAL_ENTRY(fsys_bubble_down)
or r29=r8,r29 // construct cr.ipsr value to save or r29=r8,r29 // construct cr.ipsr value to save
addl r22=IA64_RBS_OFFSET,r2 // compute base of RBS addl r22=IA64_RBS_OFFSET,r2 // compute base of RBS
;; ;;
// GAS reports a spurious RAW hazard on the read of ar.rnat because it thinks
// we may be reading ar.itc after writing to psr.l. Avoid that message with
// this directive:
dv_serialize_data
mov.m r24=ar.rnat // read ar.rnat (5 cyc lat) mov.m r24=ar.rnat // read ar.rnat (5 cyc lat)
lfetch.fault.excl.nt1 [r22] lfetch.fault.excl.nt1 [r22]
adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r2 adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r2
......
...@@ -181,6 +181,12 @@ ENTRY(vhpt_miss) ...@@ -181,6 +181,12 @@ ENTRY(vhpt_miss)
(p7) itc.d r24 (p7) itc.d r24
;; ;;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/*
* Tell the assemblers dependency-violation checker that the above "itc" instructions
* cannot possibly affect the following loads:
*/
dv_serialize_data
/* /*
* Re-check L2 and L3 pagetable. If they changed, we may have received a ptc.g * Re-check L2 and L3 pagetable. If they changed, we may have received a ptc.g
* between reading the pagetable and the "itc". If so, flush the entry we * between reading the pagetable and the "itc". If so, flush the entry we
...@@ -229,6 +235,12 @@ ENTRY(itlb_miss) ...@@ -229,6 +235,12 @@ ENTRY(itlb_miss)
itc.i r18 itc.i r18
;; ;;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/*
* Tell the assemblers dependency-violation checker that the above "itc" instructions
* cannot possibly affect the following loads:
*/
dv_serialize_data
ld8 r19=[r17] // read L3 PTE again and see if same ld8 r19=[r17] // read L3 PTE again and see if same
mov r20=PAGE_SHIFT<<2 // setup page size for purge mov r20=PAGE_SHIFT<<2 // setup page size for purge
;; ;;
...@@ -267,6 +279,12 @@ dtlb_fault: ...@@ -267,6 +279,12 @@ dtlb_fault:
itc.d r18 itc.d r18
;; ;;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/*
* Tell the assemblers dependency-violation checker that the above "itc" instructions
* cannot possibly affect the following loads:
*/
dv_serialize_data
ld8 r19=[r17] // read L3 PTE again and see if same ld8 r19=[r17] // read L3 PTE again and see if same
mov r20=PAGE_SHIFT<<2 // setup page size for purge mov r20=PAGE_SHIFT<<2 // setup page size for purge
;; ;;
...@@ -504,6 +522,12 @@ ENTRY(dirty_bit) ...@@ -504,6 +522,12 @@ ENTRY(dirty_bit)
;; ;;
(p6) itc.d r25 // install updated PTE (p6) itc.d r25 // install updated PTE
;; ;;
/*
* Tell the assemblers dependency-violation checker that the above "itc" instructions
* cannot possibly affect the following loads:
*/
dv_serialize_data
ld8 r18=[r17] // read PTE again ld8 r18=[r17] // read PTE again
;; ;;
cmp.eq p6,p7=r18,r25 // is it same as the newly installed cmp.eq p6,p7=r18,r25 // is it same as the newly installed
...@@ -563,6 +587,12 @@ ENTRY(iaccess_bit) ...@@ -563,6 +587,12 @@ ENTRY(iaccess_bit)
;; ;;
(p6) itc.i r25 // install updated PTE (p6) itc.i r25 // install updated PTE
;; ;;
/*
* Tell the assemblers dependency-violation checker that the above "itc" instructions
* cannot possibly affect the following loads:
*/
dv_serialize_data
ld8 r18=[r17] // read PTE again ld8 r18=[r17] // read PTE again
;; ;;
cmp.eq p6,p7=r18,r25 // is it same as the newly installed cmp.eq p6,p7=r18,r25 // is it same as the newly installed
...@@ -610,6 +640,11 @@ ENTRY(daccess_bit) ...@@ -610,6 +640,11 @@ ENTRY(daccess_bit)
cmp.eq p6,p7=r26,r18 cmp.eq p6,p7=r26,r18
;; ;;
(p6) itc.d r25 // install updated PTE (p6) itc.d r25 // install updated PTE
/*
* Tell the assemblers dependency-violation checker that the above "itc" instructions
* cannot possibly affect the following loads:
*/
dv_serialize_data
;; ;;
ld8 r18=[r17] // read PTE again ld8 r18=[r17] // read PTE again
;; ;;
......
...@@ -3886,8 +3886,10 @@ pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_ ...@@ -3886,8 +3886,10 @@ pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_
} else { } else {
CTX_USED_DBR(ctx, rnum); CTX_USED_DBR(ctx, rnum);
if (can_access_pmu) ia64_set_dbr(rnum, dbreg.val); if (can_access_pmu) {
ia64_set_dbr(rnum, dbreg.val);
ia64_dv_serialize_data();
}
ctx->ctx_dbrs[rnum] = dbreg.val; ctx->ctx_dbrs[rnum] = dbreg.val;
DPRINT(("write dbr%u=0x%lx used_dbrs=0x%x is_loaded=%d access_pmu=%d\n", DPRINT(("write dbr%u=0x%lx used_dbrs=0x%x is_loaded=%d access_pmu=%d\n",
...@@ -5574,7 +5576,7 @@ pfm_proc_info(char *page) ...@@ -5574,7 +5576,7 @@ pfm_proc_info(char *page)
p += sprintf(p, "fastctxsw : %s\n", pfm_sysctl.fastctxsw > 0 ? "Yes": "No"); p += sprintf(p, "fastctxsw : %s\n", pfm_sysctl.fastctxsw > 0 ? "Yes": "No");
p += sprintf(p, "expert mode : %s\n", pfm_sysctl.expert_mode > 0 ? "Yes": "No"); p += sprintf(p, "expert mode : %s\n", pfm_sysctl.expert_mode > 0 ? "Yes": "No");
p += sprintf(p, "ovfl_mask : 0x%lx\n", pmu_conf->ovfl_val); p += sprintf(p, "ovfl_mask : 0x%lx\n", pmu_conf->ovfl_val);
p += sprintf(p, "flags : 0x%lx\n", pmu_conf->flags); p += sprintf(p, "flags : 0x%x\n", pmu_conf->flags);
for(i=0; i < NR_CPUS; i++) { for(i=0; i < NR_CPUS; i++) {
if (cpu_online(i) == 0) continue; if (cpu_online(i) == 0) continue;
......
...@@ -343,6 +343,7 @@ ia64_mmu_init (void *my_cpu_data) ...@@ -343,6 +343,7 @@ ia64_mmu_init (void *my_cpu_data)
#ifdef CONFIG_HUGETLB_PAGE #ifdef CONFIG_HUGETLB_PAGE
ia64_set_rr(HPAGE_REGION_BASE, HPAGE_SHIFT << 2); ia64_set_rr(HPAGE_REGION_BASE, HPAGE_SHIFT << 2);
ia64_srlz_d();
#endif #endif
cpu = smp_processor_id(); cpu = smp_processor_id();
......
.serialize.data
.serialize.instruction
...@@ -40,4 +40,14 @@ then ...@@ -40,4 +40,14 @@ then
CPPFLAGS="$CPPFLAGS -DHAVE_MODEL_SMALL_ATTRIBUTE" CPPFLAGS="$CPPFLAGS -DHAVE_MODEL_SMALL_ATTRIBUTE"
fi fi
rm -f $out rm -f $out
# Check whether assembler supports .serialize.{data,instruction} directive.
$CC -c $dir/check-serialize.S -o $out 2>/dev/null
res=$?
rm -f $out
if [ $res -eq 0 ]; then
CPPFLAGS="$CPPFLAGS -DHAVE_SERIALIZE_DIRECTIVE"
fi
echo $CPPFLAGS echo $CPPFLAGS
...@@ -100,4 +100,12 @@ ...@@ -100,4 +100,12 @@
# define TEXT_ALIGN(n) # define TEXT_ALIGN(n)
#endif #endif
#ifdef HAVE_SERIALIZE_DIRECTIVE
# define dv_serialize_data .serialize.data
# define dv_serialize_instruction .serialize.instruction
#else
# define dv_serialize_data
# define dv_serialize_instruction
#endif
#endif /* _ASM_IA64_ASMMACRO_H */ #endif /* _ASM_IA64_ASMMACRO_H */
...@@ -377,9 +377,16 @@ register unsigned long ia64_r13 asm ("r13"); ...@@ -377,9 +377,16 @@ register unsigned long ia64_r13 asm ("r13");
}) })
#define ia64_srlz_i() asm volatile (";; srlz.i ;;" ::: "memory") #define ia64_srlz_i() asm volatile (";; srlz.i ;;" ::: "memory")
#define ia64_srlz_d() asm volatile (";; srlz.d" ::: "memory"); #define ia64_srlz_d() asm volatile (";; srlz.d" ::: "memory");
#ifdef HAVE_SERIALIZE_DIRECTIVE
# define ia64_dv_serialize_data() asm volatile (".serialize.data");
# define ia64_dv_serialize_instruction() asm volatile (".serialize.instruction");
#else
# define ia64_dv_serialize_data()
# define ia64_dv_serialize_instruction()
#endif
#define ia64_nop(x) asm volatile ("nop %0"::"i"(x)); #define ia64_nop(x) asm volatile ("nop %0"::"i"(x));
#define ia64_itci(addr) asm volatile ("itc.i %0;;" :: "r"(addr) : "memory") #define ia64_itci(addr) asm volatile ("itc.i %0;;" :: "r"(addr) : "memory")
......
...@@ -204,6 +204,9 @@ __s64 _m64_popcnt(__s64 a); ...@@ -204,6 +204,9 @@ __s64 _m64_popcnt(__s64 a);
#define ia64_srlz_d __dsrlz #define ia64_srlz_d __dsrlz
#define ia64_srlz_i __isrlz #define ia64_srlz_i __isrlz
#define ia64_dv_serialize_data()
#define ia64_dv_serialize_instruction()
#define ia64_st1_rel __st1_rel #define ia64_st1_rel __st1_rel
#define ia64_st2_rel __st2_rel #define ia64_st2_rel __st2_rel
#define ia64_st4_rel __st4_rel #define ia64_st4_rel __st4_rel
......
...@@ -114,10 +114,16 @@ extern struct ia64_boot_param { ...@@ -114,10 +114,16 @@ extern struct ia64_boot_param {
*/ */
/* For spinlocks etc */ /* For spinlocks etc */
/* clearing psr.i is implicitly serialized (visible by next insn) */ /*
/* setting psr.i requires data serialization */ * - clearing psr.i is implicitly serialized (visible by next insn)
* - setting psr.i requires data serialization
* - we need a stop-bit before reading PSR because we sometimes
* write a floating-point register right before reading the PSR
* and that writes to PSR.mfl
*/
#define __local_irq_save(x) \ #define __local_irq_save(x) \
do { \ do { \
ia64_stop(); \
(x) = ia64_getreg(_IA64_REG_PSR); \ (x) = ia64_getreg(_IA64_REG_PSR); \
ia64_stop(); \ ia64_stop(); \
ia64_rsm(IA64_PSR_I); \ ia64_rsm(IA64_PSR_I); \
...@@ -166,7 +172,7 @@ do { \ ...@@ -166,7 +172,7 @@ do { \
#endif /* !CONFIG_IA64_DEBUG_IRQ */ #endif /* !CONFIG_IA64_DEBUG_IRQ */
#define local_irq_enable() ({ ia64_ssm(IA64_PSR_I); ia64_srlz_d(); }) #define local_irq_enable() ({ ia64_ssm(IA64_PSR_I); ia64_srlz_d(); })
#define local_save_flags(flags) ((flags) = ia64_getreg(_IA64_REG_PSR)) #define local_save_flags(flags) ({ ia64_stop(); (flags) = ia64_getreg(_IA64_REG_PSR); })
#define irqs_disabled() \ #define irqs_disabled() \
({ \ ({ \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment