Re: Alpha/2.2.0-pre8 hang on boot

Richard Henderson (rth@twiddle.net)
Tue, 19 Jan 1999 20:06:33 -0800


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/