Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Browse files Browse the repository at this point in the history
Pull sparc fixes from David Miller:

 1) Fix race in sparc64 TLB shootdowns, we have to synchronize with the
    sibling cpus completing if we are passing them a reference via
    pointer to a data structure.

 2) Fix cleaning of bitmaps in sparc32, from Akinobu Mita.

 3) Fix various sparc header mistakes, some of which resulted in
    userland build breakage.  From Sam Ravnborg.

 4) Kill ghost declarations and defines missed when several bits of code
    got deleted recently.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
  sparc64: Fix race in TLB batch processing.
  sparc: use asm-generic version of types.h
  bbc_i2c: fix section mismatch warning
  sparc: use generic headers
  sparc:cleanup unused code in smp_32.h
  sparc/iommu: fix typo s/265KB/256KB/
  sparc/srmmu: clear trailing edge of bitmap properly
  sparc:remove unused declaration smp_boot_cpus()
  • Loading branch information
Linus Torvalds committed Apr 21, 2013
2 parents c437d88 + f36391d commit 851b3f3
Show file tree
Hide file tree
Showing 19 changed files with 253 additions and 114 deletions.
5 changes: 5 additions & 0 deletions arch/sparc/include/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@


generic-y += clkdev.h
generic-y += cputime.h
generic-y += div64.h
generic-y += emergency-restart.h
generic-y += exec.h
generic-y += local64.h
generic-y += mutex.h
generic-y += irq_regs.h
generic-y += local.h
generic-y += module.h
generic-y += serial.h
generic-y += trace_clock.h
generic-y += types.h
generic-y += word-at-a-time.h
6 changes: 0 additions & 6 deletions arch/sparc/include/asm/cputime.h

This file was deleted.

6 changes: 0 additions & 6 deletions arch/sparc/include/asm/emergency-restart.h

This file was deleted.

9 changes: 0 additions & 9 deletions arch/sparc/include/asm/mutex.h

This file was deleted.

1 change: 1 addition & 0 deletions arch/sparc/include/asm/pgtable_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma,
return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot);
}

#include <asm/tlbflush.h>
#include <asm-generic/pgtable.h>

/* We provide our own get_unmapped_area to cope with VA holes and
Expand Down
6 changes: 0 additions & 6 deletions arch/sparc/include/asm/serial.h

This file was deleted.

5 changes: 0 additions & 5 deletions arch/sparc/include/asm/smp_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long,
unsigned long, unsigned long);

void cpu_panic(void);
extern void smp4m_irq_rotate(int cpu);

/*
* General functions that each host system must provide.
Expand All @@ -46,7 +45,6 @@ void sun4m_init_smp(void);
void sun4d_init_smp(void);

void smp_callin(void);
void smp_boot_cpus(void);
void smp_store_cpu_info(int);

void smp_resched_interrupt(void);
Expand Down Expand Up @@ -107,9 +105,6 @@ extern int hard_smp_processor_id(void);

#define raw_smp_processor_id() (current_thread_info()->cpu)

#define prof_multiplier(__cpu) cpu_data(__cpu).multiplier
#define prof_counter(__cpu) cpu_data(__cpu).counter

void smp_setup_cpu_possible_map(void);

#endif /* !(__ASSEMBLY__) */
Expand Down
3 changes: 1 addition & 2 deletions arch/sparc/include/asm/switch_to_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ do { \
* and 2 stores in this critical code path. -DaveM
*/
#define switch_to(prev, next, last) \
do { flush_tlb_pending(); \
save_and_clear_fpu(); \
do { save_and_clear_fpu(); \
/* If you are tempted to conditionalize the following */ \
/* so that ASI is only written if it changes, think again. */ \
__asm__ __volatile__("wr %%g0, %0, %%asi" \
Expand Down
37 changes: 31 additions & 6 deletions arch/sparc/include/asm/tlbflush_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,40 @@
struct tlb_batch {
struct mm_struct *mm;
unsigned long tlb_nr;
unsigned long active;
unsigned long vaddrs[TLB_BATCH_NR];
};

extern void flush_tsb_kernel_range(unsigned long start, unsigned long end);
extern void flush_tsb_user(struct tlb_batch *tb);
extern void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr);

/* TLB flush operations. */

extern void flush_tlb_pending(void);
static inline void flush_tlb_mm(struct mm_struct *mm)
{
}

static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{
}

static inline void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
}

#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE

#define flush_tlb_range(vma,start,end) \
do { (void)(start); flush_tlb_pending(); } while (0)
#define flush_tlb_page(vma,addr) flush_tlb_pending()
#define flush_tlb_mm(mm) flush_tlb_pending()
extern void flush_tlb_pending(void);
extern void arch_enter_lazy_mmu_mode(void);
extern void arch_leave_lazy_mmu_mode(void);
#define arch_flush_lazy_mmu_mode() do {} while (0)

/* Local cpu only. */
extern void __flush_tlb_all(void);

extern void __flush_tlb_page(unsigned long context, unsigned long vaddr);
extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end);

#ifndef CONFIG_SMP
Expand All @@ -38,15 +54,24 @@ do { flush_tsb_kernel_range(start,end); \
__flush_tlb_kernel_range(start,end); \
} while (0)

static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr)
{
__flush_tlb_page(CTX_HWBITS(mm->context), vaddr);
}

#else /* CONFIG_SMP */

extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end);
extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr);

#define flush_tlb_kernel_range(start, end) \
do { flush_tsb_kernel_range(start,end); \
smp_flush_tlb_kernel_range(start, end); \
} while (0)

#define global_flush_tlb_page(mm, vaddr) \
smp_flush_tlb_page(mm, vaddr)

#endif /* ! CONFIG_SMP */

#endif /* _SPARC64_TLBFLUSH_H */
1 change: 0 additions & 1 deletion arch/sparc/include/uapi/asm/Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ header-y += swab.h
header-y += termbits.h
header-y += termios.h
header-y += traps.h
header-y += types.h
header-y += uctx.h
header-y += unistd.h
header-y += utrap.h
Expand Down
17 changes: 0 additions & 17 deletions arch/sparc/include/uapi/asm/types.h

This file was deleted.

41 changes: 37 additions & 4 deletions arch/sparc/kernel/smp_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ void smp_tsb_sync(struct mm_struct *mm)
}

extern unsigned long xcall_flush_tlb_mm;
extern unsigned long xcall_flush_tlb_pending;
extern unsigned long xcall_flush_tlb_page;
extern unsigned long xcall_flush_tlb_kernel_range;
extern unsigned long xcall_fetch_glob_regs;
extern unsigned long xcall_fetch_glob_pmu;
Expand Down Expand Up @@ -1074,23 +1074,56 @@ void smp_flush_tlb_mm(struct mm_struct *mm)
put_cpu();
}

struct tlb_pending_info {
unsigned long ctx;
unsigned long nr;
unsigned long *vaddrs;
};

static void tlb_pending_func(void *info)
{
struct tlb_pending_info *t = info;

__flush_tlb_pending(t->ctx, t->nr, t->vaddrs);
}

void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long *vaddrs)
{
u32 ctx = CTX_HWBITS(mm->context);
struct tlb_pending_info info;
int cpu = get_cpu();

info.ctx = ctx;
info.nr = nr;
info.vaddrs = vaddrs;

if (mm == current->mm && atomic_read(&mm->mm_users) == 1)
cpumask_copy(mm_cpumask(mm), cpumask_of(cpu));
else
smp_cross_call_masked(&xcall_flush_tlb_pending,
ctx, nr, (unsigned long) vaddrs,
mm_cpumask(mm));
smp_call_function_many(mm_cpumask(mm), tlb_pending_func,
&info, 1);

__flush_tlb_pending(ctx, nr, vaddrs);

put_cpu();
}

void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr)
{
unsigned long context = CTX_HWBITS(mm->context);
int cpu = get_cpu();

if (mm == current->mm && atomic_read(&mm->mm_users) == 1)
cpumask_copy(mm_cpumask(mm), cpumask_of(cpu));
else
smp_cross_call_masked(&xcall_flush_tlb_page,
context, vaddr, 0,
mm_cpumask(mm));
__flush_tlb_page(context, vaddr);

put_cpu();
}

void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
start &= PAGE_MASK;
Expand Down
6 changes: 1 addition & 5 deletions arch/sparc/lib/bitext.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,7 @@ void bit_map_clear(struct bit_map *t, int offset, int len)

void bit_map_init(struct bit_map *t, unsigned long *map, int size)
{

if ((size & 07) != 0)
BUG();
memset(map, 0, size>>3);

bitmap_zero(map, size);
memset(t, 0, sizeof *t);
spin_lock_init(&t->lock);
t->map = map;
Expand Down
2 changes: 1 addition & 1 deletion arch/sparc/mm/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#define IOMMU_RNGE IOMMU_RNGE_256MB
#define IOMMU_START 0xF0000000
#define IOMMU_WINSIZE (256*1024*1024U)
#define IOMMU_NPTES (IOMMU_WINSIZE/PAGE_SIZE) /* 64K PTEs, 265KB */
#define IOMMU_NPTES (IOMMU_WINSIZE/PAGE_SIZE) /* 64K PTEs, 256KB */
#define IOMMU_ORDER 6 /* 4096 * (1<<6) */

/* srmmu.c */
Expand Down
4 changes: 3 additions & 1 deletion arch/sparc/mm/srmmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,9 @@ static void __init srmmu_nocache_init(void)
SRMMU_NOCACHE_ALIGN_MAX, 0UL);
memset(srmmu_nocache_pool, 0, srmmu_nocache_size);

srmmu_nocache_bitmap = __alloc_bootmem(bitmap_bits >> 3, SMP_CACHE_BYTES, 0UL);
srmmu_nocache_bitmap =
__alloc_bootmem(BITS_TO_LONGS(bitmap_bits) * sizeof(long),
SMP_CACHE_BYTES, 0UL);
bit_map_init(&srmmu_nocache_map, srmmu_nocache_bitmap, bitmap_bits);

srmmu_swapper_pg_dir = __srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE);
Expand Down
38 changes: 34 additions & 4 deletions arch/sparc/mm/tlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,17 @@ static DEFINE_PER_CPU(struct tlb_batch, tlb_batch);
void flush_tlb_pending(void)
{
struct tlb_batch *tb = &get_cpu_var(tlb_batch);
struct mm_struct *mm = tb->mm;

if (tb->tlb_nr) {
flush_tsb_user(tb);
if (!tb->tlb_nr)
goto out;

if (CTX_VALID(tb->mm->context)) {
flush_tsb_user(tb);

if (CTX_VALID(mm->context)) {
if (tb->tlb_nr == 1) {
global_flush_tlb_page(mm, tb->vaddrs[0]);
} else {
#ifdef CONFIG_SMP
smp_flush_tlb_pending(tb->mm, tb->tlb_nr,
&tb->vaddrs[0]);
Expand All @@ -37,12 +43,30 @@ void flush_tlb_pending(void)
tb->tlb_nr, &tb->vaddrs[0]);
#endif
}
tb->tlb_nr = 0;
}

tb->tlb_nr = 0;

out:
put_cpu_var(tlb_batch);
}

void arch_enter_lazy_mmu_mode(void)
{
struct tlb_batch *tb = &__get_cpu_var(tlb_batch);

tb->active = 1;
}

void arch_leave_lazy_mmu_mode(void)
{
struct tlb_batch *tb = &__get_cpu_var(tlb_batch);

if (tb->tlb_nr)
flush_tlb_pending();
tb->active = 0;
}

static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
bool exec)
{
Expand All @@ -60,6 +84,12 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
nr = 0;
}

if (!tb->active) {
global_flush_tlb_page(mm, vaddr);
flush_tsb_user_page(mm, vaddr);
return;
}

if (nr == 0)
tb->mm = mm;

Expand Down
Loading

0 comments on commit 851b3f3

Please sign in to comment.