Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile

* 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

+39 -29
+1 -1
arch/tile/kernel/setup.c
··· 840 for_each_online_node(i) 841 register_one_node(i); 842 843 - for_each_present_cpu(i) 844 register_cpu(&cpu_devices[i], i); 845 846 return 0;
··· 840 for_each_online_node(i) 841 register_one_node(i); 842 843 + for (i = 0; i < smp_height * smp_width; ++i) 844 register_cpu(&cpu_devices[i], i); 845 846 return 0;
+19 -16
arch/tile/lib/memchr_32.c
··· 18 19 void *memchr(const void *s, int c, size_t n) 20 { 21 /* Get an aligned pointer. */ 22 - const uintptr_t s_int = (uintptr_t) s; 23 - const uint32_t *p = (const uint32_t *)(s_int & -4); 24 25 /* Create four copies of the byte for which we are looking. */ 26 - const uint32_t goal = 0x01010101 * (uint8_t) c; 27 28 /* Read the first word, but munge it so that bytes before the array 29 * will not match goal. ··· 43 * Note that this shift count expression works because we know 44 * shift counts are taken mod 32. 45 */ 46 - const uint32_t before_mask = (1 << (s_int << 3)) - 1; 47 - uint32_t v = (*p | before_mask) ^ (goal & before_mask); 48 49 /* Compute the address of the last byte. */ 50 - const char *const last_byte_ptr = (const char *)s + n - 1; 51 52 /* Compute the address of the word containing the last byte. */ 53 - const uint32_t *const last_word_ptr = 54 - (const uint32_t *)((uintptr_t) last_byte_ptr & -4); 55 - 56 - uint32_t bits; 57 - char *ret; 58 - 59 - if (__builtin_expect(n == 0, 0)) { 60 - /* Don't dereference any memory if the array is empty. */ 61 - return NULL; 62 - } 63 64 while ((bits = __insn_seqb(v, goal)) == 0) { 65 if (__builtin_expect(p == last_word_ptr, 0)) {
··· 18 19 void *memchr(const void *s, int c, size_t n) 20 { 21 + const uint32_t *last_word_ptr; 22 + const uint32_t *p; 23 + const char *last_byte_ptr; 24 + uintptr_t s_int; 25 + uint32_t goal, before_mask, v, bits; 26 + char *ret; 27 + 28 + if (__builtin_expect(n == 0, 0)) { 29 + /* Don't dereference any memory if the array is empty. */ 30 + return NULL; 31 + } 32 + 33 /* Get an aligned pointer. */ 34 + s_int = (uintptr_t) s; 35 + p = (const uint32_t *)(s_int & -4); 36 37 /* Create four copies of the byte for which we are looking. */ 38 + goal = 0x01010101 * (uint8_t) c; 39 40 /* Read the first word, but munge it so that bytes before the array 41 * will not match goal. ··· 31 * Note that this shift count expression works because we know 32 * shift counts are taken mod 32. 33 */ 34 + before_mask = (1 << (s_int << 3)) - 1; 35 + v = (*p | before_mask) ^ (goal & before_mask); 36 37 /* Compute the address of the last byte. */ 38 + last_byte_ptr = (const char *)s + n - 1; 39 40 /* Compute the address of the word containing the last byte. */ 41 + last_word_ptr = (const uint32_t *)((uintptr_t) last_byte_ptr & -4); 42 43 while ((bits = __insn_seqb(v, goal)) == 0) { 44 if (__builtin_expect(p == last_word_ptr, 0)) {
+19 -12
arch/tile/lib/spinlock_32.c
··· 167 * when we compare them. 168 */ 169 u32 my_ticket_; 170 - 171 - /* Take out the next ticket; this will also stop would-be readers. */ 172 - if (val & 1) 173 - val = get_rwlock(rwlock); 174 - rwlock->lock = __insn_addb(val, 1 << WR_NEXT_SHIFT); 175 - 176 - /* Extract my ticket value from the original word. */ 177 - my_ticket_ = val >> WR_NEXT_SHIFT; 178 179 /* 180 - * Wait until the "current" field matches our ticket, and 181 - * there are no remaining readers. 182 */ 183 for (;;) { 184 u32 curr_ = val >> WR_CURR_SHIFT; 185 - u32 readers = val >> RD_COUNT_SHIFT; 186 - u32 delta = ((my_ticket_ - curr_) & WR_MASK) + !!readers; 187 if (likely(delta == 0)) 188 break; 189
··· 167 * when we compare them. 168 */ 169 u32 my_ticket_; 170 + u32 iterations = 0; 171 172 /* 173 + * Wait until there are no readers, then bump up the next 174 + * field and capture the ticket value. 175 */ 176 for (;;) { 177 + if (!(val & 1)) { 178 + if ((val >> RD_COUNT_SHIFT) == 0) 179 + break; 180 + rwlock->lock = val; 181 + } 182 + delay_backoff(iterations++); 183 + val = __insn_tns((int *)&rwlock->lock); 184 + } 185 + 186 + /* Take out the next ticket and extract my ticket value. */ 187 + rwlock->lock = __insn_addb(val, 1 << WR_NEXT_SHIFT); 188 + my_ticket_ = val >> WR_NEXT_SHIFT; 189 + 190 + /* Wait until the "current" field matches our ticket. */ 191 + for (;;) { 192 u32 curr_ = val >> WR_CURR_SHIFT; 193 + u32 delta = ((my_ticket_ - curr_) & WR_MASK); 194 if (likely(delta == 0)) 195 break; 196