diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2013-07-23 17:32:04 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2013-07-31 11:51:19 -0400 |
commit | dd78bc11fb2050b6a3990d0421feca4c68ca4335 (patch) | |
tree | 7147fe5e0b3815443eea608d3dd0950ba53bb47d /arch/tile/lib | |
parent | 7d937719e3c5c6c9ad00584f6b62230d2ef7f9f1 (diff) | |
download | linux-stable-dd78bc11fb2050b6a3990d0421feca4c68ca4335.tar.gz linux-stable-dd78bc11fb2050b6a3990d0421feca4c68ca4335.tar.bz2 linux-stable-dd78bc11fb2050b6a3990d0421feca4c68ca4335.zip |
tile: convert uses of "inv" to "finv"
The "inv" (invalidate) instruction is generally less safe than "finv"
(flush and invalidate), as it will drop dirty data from the cache.
It turns out we have almost no need for "inv" (other than for the
older 32-bit architecture in some limited cases), so convert to
"finv" where possible and delete the extra "inv" infrastructure.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile/lib')
-rw-r--r-- | arch/tile/lib/cacheflush.c | 13 | ||||
-rw-r--r-- | arch/tile/lib/exports.c | 1 | ||||
-rw-r--r-- | arch/tile/lib/usercopy_32.S | 19 | ||||
-rw-r--r-- | arch/tile/lib/usercopy_64.S | 19 |
4 files changed, 8 insertions, 44 deletions
diff --git a/arch/tile/lib/cacheflush.c b/arch/tile/lib/cacheflush.c index 8f8ad814b139..2238b40abf3c 100644 --- a/arch/tile/lib/cacheflush.c +++ b/arch/tile/lib/cacheflush.c @@ -147,18 +147,21 @@ void finv_buffer_remote(void *buffer, size_t size, int hfh) force_load(p); /* - * Repeat, but with inv's instead of loads, to get rid of the + * Repeat, but with finv's instead of loads, to get rid of the * data we just loaded into our own cache and the old home L3. - * No need to unroll since inv's don't target a register. + * No need to unroll since finv's don't target a register. + * The finv's are guaranteed not to actually flush the data in + * the buffer back to their home, since we just read it, so the + * lines are clean in cache; we will only invalidate those lines. */ p = (char *)buffer + size - 1; - __insn_inv(p); + __insn_finv(p); p -= step_size; p = (char *)((unsigned long)p | (step_size - 1)); for (; p >= base; p -= step_size) - __insn_inv(p); + __insn_finv(p); - /* Wait for the load+inv's (and thus finvs) to have completed. */ + /* Wait for these finv's (and thus the first finvs) to be done. */ __insn_mf(); #ifdef __tilegx__ diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c index a93b02a25222..359b1bc52d84 100644 --- a/arch/tile/lib/exports.c +++ b/arch/tile/lib/exports.c @@ -22,7 +22,6 @@ EXPORT_SYMBOL(strnlen_user_asm); EXPORT_SYMBOL(strncpy_from_user_asm); EXPORT_SYMBOL(clear_user_asm); EXPORT_SYMBOL(flush_user_asm); -EXPORT_SYMBOL(inv_user_asm); EXPORT_SYMBOL(finv_user_asm); /* arch/tile/kernel/entry.S */ diff --git a/arch/tile/lib/usercopy_32.S b/arch/tile/lib/usercopy_32.S index b62d002af009..21ffa88ffe5f 100644 --- a/arch/tile/lib/usercopy_32.S +++ b/arch/tile/lib/usercopy_32.S @@ -109,25 +109,6 @@ STD_ENTRY(flush_user_asm) .popsection /* - * inv_user_asm takes the user target address in r0 and the - * number of bytes to invalidate in r1. - * It returns the number of not inv'able bytes (hopefully zero) in r0. - */ -STD_ENTRY(inv_user_asm) - bz r1, 2f - { movei r2, L2_CACHE_BYTES; add r1, r0, r1 } - { sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 } - { and r0, r0, r2; and r1, r1, r2 } - { sub r1, r1, r0 } -1: { inv r0; addi r1, r1, -CHIP_INV_STRIDE() } - { addi r0, r0, CHIP_INV_STRIDE(); bnzt r1, 1b } -2: { move r0, r1; jrp lr } - STD_ENDPROC(inv_user_asm) - .pushsection __ex_table,"a" - .word 1b, 2b - .popsection - -/* * finv_user_asm takes the user target address in r0 and the * number of bytes to flush-invalidate in r1. * It returns the number of not finv'able bytes (hopefully zero) in r0. diff --git a/arch/tile/lib/usercopy_64.S b/arch/tile/lib/usercopy_64.S index adb2dbbc70cd..f248d3196e5c 100644 --- a/arch/tile/lib/usercopy_64.S +++ b/arch/tile/lib/usercopy_64.S @@ -109,25 +109,6 @@ STD_ENTRY(flush_user_asm) .popsection /* - * inv_user_asm takes the user target address in r0 and the - * number of bytes to invalidate in r1. - * It returns the number of not inv'able bytes (hopefully zero) in r0. - */ -STD_ENTRY(inv_user_asm) - beqz r1, 2f - { movei r2, L2_CACHE_BYTES; add r1, r0, r1 } - { sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 } - { and r0, r0, r2; and r1, r1, r2 } - { sub r1, r1, r0 } -1: { inv r0; addi r1, r1, -CHIP_INV_STRIDE() } - { addi r0, r0, CHIP_INV_STRIDE(); bnezt r1, 1b } -2: { move r0, r1; jrp lr } - STD_ENDPROC(inv_user_asm) - .pushsection __ex_table,"a" - .quad 1b, 2b - .popsection - -/* * finv_user_asm takes the user target address in r0 and the * number of bytes to flush-invalidate in r1. * It returns the number of not finv'able bytes (hopefully zero) in r0. |