diff options
| author | Linus Torvalds <[email protected]> | 2017-12-01 19:39:12 -0500 | 
|---|---|---|
| committer | Linus Torvalds <[email protected]> | 2017-12-01 19:39:12 -0500 | 
| commit | e1ba1c99dad92c5917b22b1047cf36e4426b124a (patch) | |
| tree | e812f55a2442ad85f810b6877bbd4f5193156b84 /arch/riscv/kernel/smp.c | |
| parent | 4b1967c90af473e3a8bec00024758a3e676cea2d (diff) | |
| parent | 3b62de26cf5ef17340a0e986d3e53eb4f74f96d5 (diff) | |
Merge tag 'riscv-for-linus-4.15-rc2_cleanups' of git://git.kernel.org/pub/scm/linux/kernel/git/palmer/linux
Pull RISC-V cleanups and ABI fixes from Palmer Dabbelt:
 "This contains a handful of small cleanups that are a result of
  feedback that didn't make it into our original patch set, either
  because the feedback hadn't been given yet, I missed the original
  emails, or we weren't ready to submit the changes yet.
  I've been maintaining the various cleanup patch sets I have as their
  own branches, which I then merged together and signed. Each merge
  commit has a short summary of the changes, and each branch is based on
  your latest tag (4.15-rc1, in this case). If this isn't the right way
  to do this then feel free to suggest something else, but it seems sane
  to me.
  Here's a short summary of the changes, roughly in order of how
  interesting they are.
   - libgcc.h has been moved from include/lib, where it's the only
     member, to include/linux. This is meant to avoid tab completion
     conflicts.
   - VDSO entries for clock_get/gettimeofday/getcpu have been added.
     These are simple syscalls now, but we want to let glibc use them
     from the start so we can make them faster later.
   - A VDSO entry for instruction cache flushing has been added so
     userspace can flush the instruction cache.
   - The VDSO symbol versions for __vdso_cmpxchg{32,64} have been
     removed, as those VDSO entries don't actually exist.
   - __io_writes has been corrected to respect the given type.
   - A new READ_ONCE in arch_spin_is_locked().
   - __test_and_op_bit_ord() is now actually ordered.
   - Various small fixes throughout the tree to enable allmodconfig to
     build cleanly.
   - Removal of some dead code in our atomic support headers.
   - Improvements to various comments in our atomic support headers"
* tag 'riscv-for-linus-4.15-rc2_cleanups' of git://git.kernel.org/pub/scm/linux/kernel/git/palmer/linux: (23 commits)
  RISC-V: __io_writes should respect the length argument
  move libgcc.h to include/linux
  RISC-V: Clean up an unused include
  RISC-V: Allow userspace to flush the instruction cache
  RISC-V: Flush I$ when making a dirty page executable
  RISC-V: Add missing include
  RISC-V: Use define for get_cycles like other architectures
  RISC-V: Provide stub of setup_profiling_timer()
  RISC-V: Export some expected symbols for modules
  RISC-V: move empty_zero_page definition to C and export it
  RISC-V: io.h: type fixes for warnings
  RISC-V: use RISCV_{INT,SHORT} instead of {INT,SHORT} for asm macros
  RISC-V: use generic serial.h
  RISC-V: remove spin_unlock_wait()
  RISC-V: `sfence.vma` orderes the instruction cache
  RISC-V: Add READ_ONCE in arch_spin_is_locked()
  RISC-V: __test_and_op_bit_ord should be strongly ordered
  RISC-V: Remove smb_mb__{before,after}_spinlock()
  RISC-V: Remove __smp_bp__{before,after}_atomic
  RISC-V: Comment on why {,cmp}xchg is ordered how it is
  ...
Diffstat (limited to 'arch/riscv/kernel/smp.c')
| -rw-r--r-- | arch/riscv/kernel/smp.c | 55 | 
1 files changed, 55 insertions, 0 deletions
| diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c index b4a71ec5906f..6d3962435720 100644 --- a/arch/riscv/kernel/smp.c +++ b/arch/riscv/kernel/smp.c @@ -38,6 +38,13 @@ enum ipi_message_type {  	IPI_MAX  }; + +/* Unsupported */ +int setup_profiling_timer(unsigned int multiplier) +{ +	return -EINVAL; +} +  irqreturn_t handle_ipi(void)  {  	unsigned long *pending_ipis = &ipi_data[smp_processor_id()].bits; @@ -108,3 +115,51 @@ void smp_send_reschedule(int cpu)  {  	send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE);  } + +/* + * Performs an icache flush for the given MM context.  RISC-V has no direct + * mechanism for instruction cache shoot downs, so instead we send an IPI that + * informs the remote harts they need to flush their local instruction caches. + * To avoid pathologically slow behavior in a common case (a bunch of + * single-hart processes on a many-hart machine, ie 'make -j') we avoid the + * IPIs for harts that are not currently executing a MM context and instead + * schedule a deferred local instruction cache flush to be performed before + * execution resumes on each hart. + */ +void flush_icache_mm(struct mm_struct *mm, bool local) +{ +	unsigned int cpu; +	cpumask_t others, *mask; + +	preempt_disable(); + +	/* Mark every hart's icache as needing a flush for this MM. */ +	mask = &mm->context.icache_stale_mask; +	cpumask_setall(mask); +	/* Flush this hart's I$ now, and mark it as flushed. */ +	cpu = smp_processor_id(); +	cpumask_clear_cpu(cpu, mask); +	local_flush_icache_all(); + +	/* +	 * Flush the I$ of other harts concurrently executing, and mark them as +	 * flushed. +	 */ +	cpumask_andnot(&others, mm_cpumask(mm), cpumask_of(cpu)); +	local |= cpumask_empty(&others); +	if (mm != current->active_mm || !local) +		sbi_remote_fence_i(others.bits); +	else { +		/* +		 * It's assumed that at least one strongly ordered operation is +		 * performed on this hart between setting a hart's cpumask bit +		 * and scheduling this MM context on that hart.  Sending an SBI +		 * remote message will do this, but in the case where no +		 * messages are sent we still need to order this hart's writes +		 * with flush_icache_deferred(). +		 */ +		smp_mb(); +	} + +	preempt_enable(); +} |