Unverified Commit c9c0b0ba authored by Palmer Dabbelt's avatar Palmer Dabbelt
Browse files

RISC-V: Move to queued RW locks



Now that we have fair spinlocks we can use the generic queued rwlocks,
so we might as well do so.

Reviewed-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent 4922a3ea
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ config RISCV
	select ARCH_SUPPORTS_DEBUG_PAGEALLOC if MMU
	select ARCH_SUPPORTS_HUGETLBFS if MMU
	select ARCH_USE_MEMTEST
	select ARCH_USE_QUEUED_RWLOCKS
	select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
	select ARCH_WANT_FRAME_POINTERS
	select ARCH_WANT_GENERAL_HUGETLB
+2 −0
Original line number Diff line number Diff line
@@ -3,6 +3,8 @@ generic-y += early_ioremap.h
generic-y += flat.h
generic-y += kvm_para.h
generic-y += parport.h
generic-y += spinlock.h
generic-y += spinlock_types.h
generic-y += qrwlock.h
generic-y += qrwlock_types.h
generic-y += user.h

arch/riscv/include/asm/spinlock.h

deleted100644 → 0
+0 −99
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (C) 2015 Regents of the University of California
 * Copyright (C) 2017 SiFive
 */

#ifndef _ASM_RISCV_SPINLOCK_H
#define _ASM_RISCV_SPINLOCK_H

/* This is horible, but the whole file is going away in the next commit. */
#define __ASM_GENERIC_QRWLOCK_H

#include <linux/kernel.h>
#include <asm/current.h>
#include <asm/fence.h>
#include <asm-generic/spinlock.h>

static inline void arch_read_lock(arch_rwlock_t *lock)
{
	int tmp;

	__asm__ __volatile__(
		"1:	lr.w	%1, %0\n"
		"	bltz	%1, 1b\n"
		"	addi	%1, %1, 1\n"
		"	sc.w	%1, %1, %0\n"
		"	bnez	%1, 1b\n"
		RISCV_ACQUIRE_BARRIER
		: "+A" (lock->lock), "=&r" (tmp)
		:: "memory");
}

static inline void arch_write_lock(arch_rwlock_t *lock)
{
	int tmp;

	__asm__ __volatile__(
		"1:	lr.w	%1, %0\n"
		"	bnez	%1, 1b\n"
		"	li	%1, -1\n"
		"	sc.w	%1, %1, %0\n"
		"	bnez	%1, 1b\n"
		RISCV_ACQUIRE_BARRIER
		: "+A" (lock->lock), "=&r" (tmp)
		:: "memory");
}

static inline int arch_read_trylock(arch_rwlock_t *lock)
{
	int busy;

	__asm__ __volatile__(
		"1:	lr.w	%1, %0\n"
		"	bltz	%1, 1f\n"
		"	addi	%1, %1, 1\n"
		"	sc.w	%1, %1, %0\n"
		"	bnez	%1, 1b\n"
		RISCV_ACQUIRE_BARRIER
		"1:\n"
		: "+A" (lock->lock), "=&r" (busy)
		:: "memory");

	return !busy;
}

static inline int arch_write_trylock(arch_rwlock_t *lock)
{
	int busy;

	__asm__ __volatile__(
		"1:	lr.w	%1, %0\n"
		"	bnez	%1, 1f\n"
		"	li	%1, -1\n"
		"	sc.w	%1, %1, %0\n"
		"	bnez	%1, 1b\n"
		RISCV_ACQUIRE_BARRIER
		"1:\n"
		: "+A" (lock->lock), "=&r" (busy)
		:: "memory");

	return !busy;
}

static inline void arch_read_unlock(arch_rwlock_t *lock)
{
	__asm__ __volatile__(
		RISCV_RELEASE_BARRIER
		"	amoadd.w x0, %1, %0\n"
		: "+A" (lock->lock)
		: "r" (-1)
		: "memory");
}

static inline void arch_write_unlock(arch_rwlock_t *lock)
{
	smp_store_release(&lock->lock, 0);
}

#endif /* _ASM_RISCV_SPINLOCK_H */
+0 −24
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (C) 2015 Regents of the University of California
 */

#ifndef _ASM_RISCV_SPINLOCK_TYPES_H
#define _ASM_RISCV_SPINLOCK_TYPES_H

/* This is horible, but the whole file is going away in the next commit. */
#define __ASM_GENERIC_QRWLOCK_TYPES_H

#ifndef __LINUX_SPINLOCK_TYPES_RAW_H
# error "please don't include this file directly"
#endif

#include <asm-generic/spinlock_types.h>

typedef struct {
	volatile unsigned int lock;
} arch_rwlock_t;

#define __ARCH_RW_LOCK_UNLOCKED		{ 0 }

#endif /* _ASM_RISCV_SPINLOCK_TYPES_H */