Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile
Browse files Browse the repository at this point in the history
* git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile:
  arch/tile: fix memchr() not to dereference memory for zero length
  arch/tile: make glibc's sysconf(_SC_NPROCESSORS_CONF) work correctly
  arch/tile: fix rwlock so would-be write lockers don't block new readers
  • Loading branch information
torvalds committed Nov 24, 2010
2 parents 47143b0 + 3edabee commit c12ae95
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 28 deletions.
2 changes: 1 addition & 1 deletion arch/tile/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,7 @@ static int __init topology_init(void)
for_each_online_node(i)
register_one_node(i);

for_each_present_cpu(i)
for (i = 0; i < smp_height * smp_width; ++i)
register_cpu(&cpu_devices[i], i);

return 0;
Expand Down
35 changes: 19 additions & 16 deletions arch/tile/lib/memchr_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,39 @@

void *memchr(const void *s, int c, size_t n)
{
const uint32_t *last_word_ptr;
const uint32_t *p;
const char *last_byte_ptr;
uintptr_t s_int;
uint32_t goal, before_mask, v, bits;
char *ret;

if (__builtin_expect(n == 0, 0)) {
/* Don't dereference any memory if the array is empty. */
return NULL;
}

/* Get an aligned pointer. */
const uintptr_t s_int = (uintptr_t) s;
const uint32_t *p = (const uint32_t *)(s_int & -4);
s_int = (uintptr_t) s;
p = (const uint32_t *)(s_int & -4);

/* Create four copies of the byte for which we are looking. */
const uint32_t goal = 0x01010101 * (uint8_t) c;
goal = 0x01010101 * (uint8_t) c;

/* Read the first word, but munge it so that bytes before the array
* will not match goal.
*
* Note that this shift count expression works because we know
* shift counts are taken mod 32.
*/
const uint32_t before_mask = (1 << (s_int << 3)) - 1;
uint32_t v = (*p | before_mask) ^ (goal & before_mask);
before_mask = (1 << (s_int << 3)) - 1;
v = (*p | before_mask) ^ (goal & before_mask);

/* Compute the address of the last byte. */
const char *const last_byte_ptr = (const char *)s + n - 1;
last_byte_ptr = (const char *)s + n - 1;

/* Compute the address of the word containing the last byte. */
const uint32_t *const last_word_ptr =
(const uint32_t *)((uintptr_t) last_byte_ptr & -4);

uint32_t bits;
char *ret;

if (__builtin_expect(n == 0, 0)) {
/* Don't dereference any memory if the array is empty. */
return NULL;
}
last_word_ptr = (const uint32_t *)((uintptr_t) last_byte_ptr & -4);

while ((bits = __insn_seqb(v, goal)) == 0) {
if (__builtin_expect(p == last_word_ptr, 0)) {
Expand Down
29 changes: 18 additions & 11 deletions arch/tile/lib/spinlock_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,23 +167,30 @@ void arch_write_lock_slow(arch_rwlock_t *rwlock, u32 val)
* when we compare them.
*/
u32 my_ticket_;
u32 iterations = 0;

/* Take out the next ticket; this will also stop would-be readers. */
if (val & 1)
val = get_rwlock(rwlock);
rwlock->lock = __insn_addb(val, 1 << WR_NEXT_SHIFT);
/*
* Wait until there are no readers, then bump up the next
* field and capture the ticket value.
*/
for (;;) {
if (!(val & 1)) {
if ((val >> RD_COUNT_SHIFT) == 0)
break;
rwlock->lock = val;
}
delay_backoff(iterations++);
val = __insn_tns((int *)&rwlock->lock);
}

/* Extract my ticket value from the original word. */
/* Take out the next ticket and extract my ticket value. */
rwlock->lock = __insn_addb(val, 1 << WR_NEXT_SHIFT);
my_ticket_ = val >> WR_NEXT_SHIFT;

/*
* Wait until the "current" field matches our ticket, and
* there are no remaining readers.
*/
/* Wait until the "current" field matches our ticket. */
for (;;) {
u32 curr_ = val >> WR_CURR_SHIFT;
u32 readers = val >> RD_COUNT_SHIFT;
u32 delta = ((my_ticket_ - curr_) & WR_MASK) + !!readers;
u32 delta = ((my_ticket_ - curr_) & WR_MASK);
if (likely(delta == 0))
break;

Expand Down

0 comments on commit c12ae95

Please sign in to comment.