lkml.org 
[lkml]   [2000]   [Feb]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: 2.3.42 crashes on boot (Was: [PATCH] devfs v99.11 available)
On Thu, Feb 10, 2000 at 10:19:03PM +1100, Richard Gooch wrote:
> Sergey Kubushin writes:
> > On Wed, 9 Feb 2000, Richard Gooch wrote:
> >
> > > NOTE: the devfs-patch-v99.x patches are maintenance patches for the
> > > 2.2.x production kernels. Devfs development is done against recent
> > > development kernels. Occasionally, the latest devfs patch for the
> > > development kernels may be backported to 2.2.x series, but this
> > > happens rarely.
> > >
> > > This is against 2.2.14. Highlights of this release:
> > >
> > > - Ported devfs-patch-v99.10 to kernel 2.2.14
> > >
> > > - Moved /dev/tty0 to /dev/vc/0
> >
> > It's very nice, but can somebody explain why 2.3.42 with devfs v.154
> > crashes on boot ? Initrd strikes back ?
>
> Odd. Please send me (off-list) your /etc/lilo.conf so I can see
> exactly what is being passed to the kernel.
>
> > Here is the oops:
> >
> > === Cut ===
> > ksymoops 0.7c on i686 2.3.36. Options used
> > -V (specified)
> > -K (specified)
> > -L (specified)
> > -o /lib/modules/kernel/2.3.42/ (specified)
> > -m /boot/System.map-2.3.42 (specified)
> >
> > No modules in ksyms, skipping objects
> > Unable to handle kernel NULL pointer dereference at virtual address 00000038
> > c0149ba1
> > *pde = 00104001
> > Oops: 0000
> > CPU: 0
> > EIP: 0010:[<c0149ba1>]
> > Using defaults from ksymoops -t elf32-i386 -a i386
> > EFLAGS: 00010246
> > eax: 00000038 ebx: 00000000 ecx: c02839f2 edx: c14fbe54
> > esi: 00000018 edi: c14fbe54 ebp: ffffffed esp: c14fbb00
> > ds: 0018 es: 0018 ss: 0018
> > Process swapper (pid: 1, stackpage=c14fb000)
> > Stack: 00000100 00000000 c14fbb6c c14fbd04 c0283acd c14fbe54 c14fbca8 c02a00e0
> > c0277fc8 00000000 00001000 c02839f2 00000000 c14fbb6c 00000000 00000000
> > 00000000 00000000 c14fbc4c c14fbe54 c14fbca8 00000000 00000000 00000000
> > Call Trace: [<c0110018>] [<c01081cb>] [<c010a010>]
> > Code: 39 46 20 74 2a 50 8b 46 20 50 68 c0 9e 21 c0 e8 53 52 fd ff
> >
> > >>EIP; c0149ba1 <blkdev_open+19/dc> <=====
> > Trace; c0110018 <do_int+a8/1b4>
> > Trace; c01081cb <init+5f/1e4>
> > Trace; c010a010 <kernel_thread+28/38>
> > Code; c0149ba1 <blkdev_open+19/dc>
> > 00000000 <_EIP>:
> > Code; c0149ba1 <blkdev_open+19/dc> <=====
> > 0: 39 46 20 cmp %eax,0x20(%esi) <=====
> > Code; c0149ba4 <blkdev_open+1c/dc>
> > 3: 74 2a je 2f <_EIP+0x2f> c0149bd0 <blkdev_open+48/dc>
> > Code; c0149ba6 <blkdev_open+1e/dc>
> > 5: 50 push %eax
> > Code; c0149ba7 <blkdev_open+1f/dc>
> > 6: 8b 46 20 mov 0x20(%esi),%eax
> > Code; c0149baa <blkdev_open+22/dc>
> > 9: 50 push %eax
> > Code; c0149bab <blkdev_open+23/dc>
> > a: 68 c0 9e 21 c0 push $0xc0219ec0
> > Code; c0149bb0 <blkdev_open+28/dc>
> > f: e8 53 52 fd ff call fffd5267 <_EIP+0xfffd5267> c011ee08 <printk+0/1f4>
> > === Cut ===
>
> If it crashes during boot (say mounting root), I would have expected
> mount_root() to appear in this traceback. Odd that it's not. Can you
> start sprinkling printk()'s around to figure out where blkdev_open()
> is being called from when this happens?
>
> Also, I'll need details of how you're using initrd (whether you leave
> it mounted after switching root and so on).
>
> Regards,
>
> Richard....
> Old: rgooch@atnf.csiro.au
> Current: rgooch@ras.ucalgary.ca

I don't believe that the problem described is in devfs. It was introduced
some time after 2.3.35 in the reworking of the block device interface.

With the patches below, I can boot an initrd/ramdisk system using 2.3.42
with devfs, and it appears to run properly.

PLEASE note the following:

1. There is some kind of recent breakage of ramdisk that this does not
completely fix. The symptom is that __sometimes__ files in the page
cache are not flushed to the ramdisk buffer cache. Sometimes it works
correctly.

2. The patch for initrd reading/writing is a hybrid of my earlier version
and the one from Mike Galbraith, as mine was incomplete.

3. This patch kludges out the effect of the recent "invalidate device
buffers on the final close" that destroys ramdisks.

4. Since it is 5AM, I can't remember what else I should mention here.

========================================================================
--- linux/fs/block_dev.c.orig Sun Feb 6 01:56:39 2000
+++ linux/fs/block_dev.c Mon Feb 7 00:06:41 2000
@@ -616,7 +616,8 @@
/* syncing will go here */
if (kind == BDEV_FILE || kind == BDEV_FS)
fsync_dev(rdev);
- if (atomic_dec_and_test(&bdev->bd_openers)) {
+ if (atomic_dec_and_test(&bdev->bd_openers) &&
+ MAJOR(rdev) != RAMDISK_MAJOR) {
/* invalidating buffers will go here */
invalidate_buffers(rdev);
}
--- linux/drivers/block/rd.c.orig Sun Feb 6 01:56:33 2000
+++ linux/drivers/block/rd.c Mon Feb 7 00:08:14 2000
@@ -217,24 +217,23 @@
}

/*
- * This has become somewhat more complicated with the addition of
- * the page cache. The problem is that in some cases the furnished
+ * There is a problem here in that in some cases the furnished
* buffer is "real", i.e., part of the existing ramdisk, while in
* others it is "unreal", e.g., part of a page. In the first case
* not much needs to be done, while in the second, some kind of
* transfer is needed.
*
- * The two cases are distinguished here by checking whether the
- * real buffer is already in the buffer cache, and whether it is
- * the same as the one supplied.
+ * The two cases are distinguished by checking whether the real
+ * buffer is already in the buffer cache, and whether it matches
+ * the one supplied.
*
* There are three cases with read/write to consider:
*
- * 1. Supplied buffer matched one in the buffer cache:
- * Read - Clear the buffer, as it wasn't already valid.
+ * 1. Supplied buffer matched the one in the buffer cache:
+ * Read - Clear the buffer, as it wasn't previously valid.
* Write - Mark the buffer as "Protected".
*
- * 2. Supplied buffer mismatched one in the buffer cache:
+ * 2. Supplied buffer mismatched the one in the buffer cache:
* Read - Copy the data from the buffer cache entry.
* Write - Copy the data to the buffer cache entry.
*
@@ -243,19 +242,13 @@
* one.
* Write - Create a real buffer, copy the data to it, and mark
* it as "Protected".
- *
- * NOTE: There seems to be some schizophrenia here - the logic
- * using "len" seems to assume arbitrary request lengths, while
- * the "protect" logic assumes a single buffer cache entry.
- * This seems to be left over from the ancient contiguous ramdisk
- * logic.
*/

sbh = CURRENT->bh;
rbh = get_hash_table(sbh->b_dev, sbh->b_blocknr, sbh->b_size);
if (sbh == rbh) {
if (CURRENT->cmd == READ)
- memset(CURRENT->buffer, 1, len);
+ memset(CURRENT->buffer, 0, len);
} else if (rbh) {
if (CURRENT->cmd == READ)
memcpy(CURRENT->buffer, rbh->b_data, rbh->b_size);
@@ -263,14 +256,18 @@
memcpy(rbh->b_data, CURRENT->buffer, rbh->b_size);
} else { /* !rbh */
if (CURRENT->cmd == READ)
- memset(sbh->b_data, 2, len);
+ memset(sbh->b_data, 0, len);
else {
rbh = getblk(sbh->b_dev, sbh->b_blocknr, sbh->b_size);
if (rbh)
memcpy(rbh->b_data, CURRENT->buffer,
rbh->b_size);
- else
- BUG(); /* No buffer, what to do here? */
+ else {
+ printk(KERN_ERR "RAMDISK: "
+ "could not allocate buffer\n");
+ end_request(0);
+ goto repeat;
+ }
}
}
if (rbh) {
@@ -342,17 +339,8 @@


static struct file_operations initrd_fops = {
- NULL, /* lseek */
- initrd_read, /* read */
- NULL, /* write */
- NULL, /* readdir */
- NULL, /* poll */
- NULL, /* ioctl */
- NULL, /* mmap */
- NULL, /* open */
- NULL, /* flush */
- initrd_release, /* release */
- NULL /* fsync */
+ release: initrd_release,
+ read: initrd_read,
};

#endif
@@ -591,19 +579,21 @@
memset(&infile, 0, sizeof(infile));
memset(&inode, 0, sizeof(inode));
memset(&in_dentry, 0, sizeof(in_dentry));
- inode.i_rdev = device;
+ init_special_inode(&inode, S_IFBLK | S_IRWXU, device);
init_waitqueue_head(&inode.i_wait);
infile.f_mode = 1; /* read only */
infile.f_dentry = &in_dentry;
+ infile.f_op = &initrd_fops;
in_dentry.d_inode = &inode;

memset(&outfile, 0, sizeof(outfile));
memset(&out_inode, 0, sizeof(out_inode));
memset(&out_dentry, 0, sizeof(out_dentry));
- out_inode.i_rdev = ram_device;
+ init_special_inode(&out_inode, S_IFBLK | S_IRWXU, ram_device);
init_waitqueue_head(&out_inode.i_wait);
outfile.f_mode = 3; /* read/write */
outfile.f_dentry = &out_dentry;
+ outfile.f_op = &def_blk_fops;
out_dentry.d_inode = &out_inode;

if (blkdev_open(&inode, &infile) != 0) return;
========================================================================
--
B. D. Elliott bde@nwlink.com (Seattle)

-
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/

\
 
 \ /
  Last update: 2005-03-22 13:56    [W:0.108 / U:0.148 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site