Commit 193dd2ce authored by Ralf Baechle's avatar Ralf Baechle

[MIPS] R2: Implement shadow register allocation without spinlock.

Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 62a44215
...@@ -961,15 +961,19 @@ void *set_except_vector(int n, void *addr) ...@@ -961,15 +961,19 @@ void *set_except_vector(int n, void *addr)
#ifdef CONFIG_CPU_MIPSR2 #ifdef CONFIG_CPU_MIPSR2
/* /*
* Shadow register allocation * MIPSR2 shadow register set allocation
* FIXME: SMP... * FIXME: SMP...
*/ */
/* MIPSR2 shadow register sets */ static struct shadow_registers {
struct shadow_registers { /*
spinlock_t sr_lock; /* */ * Number of shadow register sets supported
int sr_supported; /* Number of shadow register sets supported */ */
int sr_allocated; /* Bitmap of allocated shadow registers */ unsigned long sr_supported;
/*
* Bitmap of allocated shadow registers
*/
unsigned long sr_allocated;
} shadow_registers; } shadow_registers;
void mips_srs_init(void) void mips_srs_init(void)
...@@ -980,7 +984,6 @@ void mips_srs_init(void) ...@@ -980,7 +984,6 @@ void mips_srs_init(void)
shadow_registers.sr_supported); shadow_registers.sr_supported);
#endif #endif
shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */ shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */
spin_lock_init(&shadow_registers.sr_lock);
} }
int mips_srs_max(void) int mips_srs_max(void)
...@@ -991,32 +994,24 @@ int mips_srs_max(void) ...@@ -991,32 +994,24 @@ int mips_srs_max(void)
int mips_srs_alloc(void) int mips_srs_alloc(void)
{ {
struct shadow_registers *sr = &shadow_registers; struct shadow_registers *sr = &shadow_registers;
unsigned long flags;
int set; int set;
spin_lock_irqsave(&sr->sr_lock, flags); again:
set = find_first_zero_bit(&sr->sr_allocated, sr->sr_supported);
if (set >= sr->sr_supported)
return -1;
for (set = 0; set < sr->sr_supported; set++) { if (test_and_set_bit(set, &sr->sr_allocated))
if ((sr->sr_allocated & (1 << set)) == 0) { goto again;
sr->sr_allocated |= 1 << set;
spin_unlock_irqrestore(&sr->sr_lock, flags);
return set;
}
}
/* None available */ return set;
spin_unlock_irqrestore(&sr->sr_lock, flags);
return -1;
} }
void mips_srs_free (int set) void mips_srs_free (int set)
{ {
struct shadow_registers *sr = &shadow_registers; struct shadow_registers *sr = &shadow_registers;
unsigned long flags;
spin_lock_irqsave(&sr->sr_lock, flags); clear_bit(set, &sr->sr_allocated);
sr->sr_allocated &= ~(1 << set);
spin_unlock_irqrestore(&sr->sr_lock, flags);
} }
static void *set_vi_srs_handler(int n, void *addr, int srs) static void *set_vi_srs_handler(int n, void *addr, int srs)
......
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