Messages in this thread Patch in this message | | | Date | Tue, 19 Jan 1999 20:06:33 -0800 | From | Richard Henderson <> | Subject | Re: Alpha/2.2.0-pre8 hang on boot |
| |
On Tue, Jan 19, 1999 at 09:35:31PM +0100, Matthias Welwarsky wrote: > 2.2.0-pre8 (official :-) hangs on boot while detecting scsi devices...
The hang is due to the semaphore stuff, and so must be my fault. I swear my system was up for over a day with that patch; I must have made some last minute change before sending it on, though I don't remember doing it.
Anyway, that's the one character fix at the end of semaphore.h.
The oopses people are seeing are due to the select/poll changes. DaveM was kind enough to leave me a fix in my mailbox this morning. (Linus, his did contain one little mistake -- use this instead.)
r~
diff -rup 2.2.0-pre8/include/asm-alpha/semaphore.h 2.2.0-pre8-axp/include/asm-alpha/semaphore.h --- 2.2.0-pre8/include/asm-alpha/semaphore.h Tue Jan 19 19:50:18 1999 +++ 2.2.0-pre8-axp/include/asm-alpha/semaphore.h Tue Jan 19 20:02:07 1999 @@ -72,13 +72,13 @@ extern void __up_wakeup(struct semaphore * count = -1, waking = 0, depth = 2; * up(&sem) * dec depth - * count = -1, waking = 0, depth = 0; + * count = -1, waking = 0, depth = 1; * atomic inc and test sends us to slow path - * count = 0, waking = 0, depth = 0; + * count = 0, waking = 0, depth = 1; * notice !(depth < 0) and don't call __up. * up(&sem) * dec depth - * count = 0, waking = 0, depth = -1; + * count = 0, waking = 0, depth = 0; * atomic inc and test succeeds. * count = 1, waking = 0, depth = 0; */ @@ -227,7 +227,7 @@ extern inline void up(struct semaphore * ".section .text2,\"ax\"\n" "2: br 1b\n" "3: lda $24,%1\n" - " bge %2,4b\n" + " bgt %2,4b\n" " jsr $28,__up_wakeup\n" " ldgp $29,0($28)\n" " br 4b\n" diff -rup 2.2.0-pre8/include/linux/poll.h 2.2.0-pre8-axp/include/linux/poll.h --- 2.2.0-pre8/include/linux/poll.h Tue Jan 19 19:50:18 1999 +++ 2.2.0-pre8-axp/include/linux/poll.h Tue Jan 19 19:39:59 1999 @@ -72,15 +72,6 @@ extern inline void poll_wait(struct file typedef unsigned long kernel_fd_set[KFDS_NR/__NFDBITS]; /* - * XXX - still used by alpha osf and sparc32 compatiblity. - */ - -typedef struct { - kernel_fd_set in, out, ex; - kernel_fd_set res_in, res_out, res_ex; -} fd_set_buffer; - -/* * Scaleable version of the fd_set. */ diff -rup 2.2.0-pre8/arch/alpha/kernel/osf_sys.c 2.2.0-pre8-axp/arch/alpha/kernel/osf_sys.c --- 2.2.0-pre8/arch/alpha/kernel/osf_sys.c Mon Dec 28 16:15:16 1998 +++ 2.2.0-pre8-axp/arch/alpha/kernel/osf_sys.c Tue Jan 19 19:43:25 1999 @@ -1128,11 +1128,16 @@ asmlinkage int osf_utimes(const char *fi return ret; } +#define MAX_SELECT_SECONDS \ + ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1) + asmlinkage int osf_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval32 *tvp) { - fd_set_buffer *fds; + fd_set_bits fds; + char *bits; + size_t size; unsigned long timeout; int ret; @@ -1145,28 +1150,46 @@ osf_select(int n, fd_set *inp, fd_set *o || (ret = __get_user(usec, &tvp->tv_usec))) goto out_nofds; - timeout = (usec + 1000000/HZ - 1) / (1000000/HZ); - timeout += sec * HZ; + ret = -EINVAL; + if (sec < 0 || usec < 0) + goto out_nofds; + + if ((unsigned long) sec < MAX_SELECT_SECONDS) { + timeout = (usec + 1000000/HZ - 1) / (1000000/HZ); + timeout += sec * (unsigned long) HZ; + } } + ret = -EINVAL; + if (n < 0 || n > KFDS_NR) + goto out_nofds; + + /* + * We need 6 bitmaps (in/out/ex for both incoming and outgoing), + * since we used fdset we need to allocate memory in units of + * long-words. + */ ret = -ENOMEM; - fds = (fd_set_buffer *) __get_free_page(GFP_KERNEL); - if (!fds) + size = FDS_BYTES(n); + bits = kmalloc(6 * size, GFP_KERNEL); + if (!bits) goto out_nofds; - ret = -EINVAL; - if (n < 0) - goto out; - if (n > KFDS_NR) - n = KFDS_NR; - if ((ret = get_fd_set(n, inp->fds_bits, fds->in)) || - (ret = get_fd_set(n, outp->fds_bits, fds->out)) || - (ret = get_fd_set(n, exp->fds_bits, fds->ex))) + fds.in = (unsigned long *) bits; + fds.out = (unsigned long *) (bits + size); + fds.ex = (unsigned long *) (bits + 2*size); + fds.res_in = (unsigned long *) (bits + 3*size); + fds.res_out = (unsigned long *) (bits + 4*size); + fds.res_ex = (unsigned long *) (bits + 5*size); + + if ((ret = get_fd_set(n, inp->fds_bits, fds.in)) || + (ret = get_fd_set(n, outp->fds_bits, fds.out)) || + (ret = get_fd_set(n, exp->fds_bits, fds.ex))) goto out; - zero_fd_set(n, fds->res_in); - zero_fd_set(n, fds->res_out); - zero_fd_set(n, fds->res_ex); + zero_fd_set(n, fds.res_in); + zero_fd_set(n, fds.res_out); + zero_fd_set(n, fds.res_ex); - ret = do_select(n, fds, &timeout); + ret = do_select(n, &fds, &timeout); /* OSF does not copy back the remaining time. */ @@ -1179,12 +1202,12 @@ osf_select(int n, fd_set *inp, fd_set *o ret = 0; } - set_fd_set(n, inp->fds_bits, fds->res_in); - set_fd_set(n, outp->fds_bits, fds->res_out); - set_fd_set(n, exp->fds_bits, fds->res_ex); + set_fd_set(n, inp->fds_bits, fds.res_in); + set_fd_set(n, outp->fds_bits, fds.res_out); + set_fd_set(n, exp->fds_bits, fds.res_ex); out: - free_page((unsigned long) fds); + kfree(bits); out_nofds: return ret; } @@ -1304,7 +1327,6 @@ asmlinkage int osf_usleep_thread(struct { struct timeval tmp; unsigned long ticks; - unsigned long tmp_timeout; if (get_tv32(&tmp, sleep)) goto fault; - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |