All of lore.kernel.org
 help / color / mirror / Atom feed
From: Olaf Titz <olaf@bigred.inka.de>
To: Andrew de Quincey <adq_dvb@lidskialf.net>
Cc: linux-dvb@linuxtv.org, linux-kernel@vger.kernel.org
Subject: Re: [linux-dvb] Re: dvb-kernel crasher
Date: Thu, 06 Jan 2005 17:26:52 +0100	[thread overview]
Message-ID: <41DD66CC.9070805@bigred.inka.de> (raw)
In-Reply-To: <200501051404.43182.adq_dvb@lidskialf.net>

Hello,

[CC to linux-kernel]

After more debugging I found the most likely suspect to be GCC 3.3.3.
Compiling with GCC 2.95 makes the problem go away.

Here's more analysis:

1. I tried with preempt off since the fops_get path gets much more
complex with preempt. Same result, i.e. crashes. The following is with 
preempt off.
2. Inserted debug into try_module_get. The crash happens before
try_module_get is called.

The relevant routines look now like the following (no functional
changes, only debug output):


static inline int try_module_get(struct module *module)
{
	int ret = 1;

	if (module) {
		unsigned int cpu = get_cpu();
#ifdef DEBUG_DVB
                 printk(KERN_DEBUG
                        "try_module_get(%s): cpu=%d state=%d count=%d ",
                        module->name, module->state, 
module->ref[cpu].count);
#endif
		if (likely(module_is_live(module)))
			local_inc(&module->ref[cpu].count);
		else
			ret = 0;
		put_cpu();
#ifdef DEBUG_DVB
                 printk("ret=%d\n", ret);
#endif
	}
	return ret;
}

static int dvb_device_open(struct inode *inode, struct file *file)
{
	struct dvb_device *dvbdev;

	dvbdev = dvbdev_find_device (iminor(inode));
         if (dvbdev_debug) {
             printk(KERN_DEBUG "dvb_device_open: i_rdev=%x ", 
inode->i_rdev);
             if (dvbdev) {
                 print_symbol("dvbdev=%s ", dvbdev);
                 print_symbol("fops=%s ", dvbdev ? dvbdev->fops : 0);
             } else {
                 printk("dvbdev=NULL ");
             }
             printk("file=%p ", file);
             print_symbol("f_op=%s ", file->f_op);
             printk("f_flags=%x private_data=%x\n",
                    file->f_flags, file->private_data);
         }
	if (dvbdev && dvbdev->fops) {
  		int err = 0;
		struct file_operations *old_fops;

		file->private_data = dvbdev; /**** see below ****/
		old_fops = file->f_op; /**** see below ****/
                 file->f_op = fops_get(dvbdev->fops);
                 if (dvbdev_debug)
                         print_symbol("dvb_device_open: open=%s ",
                                      file->f_op->open);
                 if(file->f_op->open)
                         err = file->f_op->open(inode,file);
                 if (err) {
                         fops_put(file->f_op);
                         file->f_op = fops_get(old_fops);
                 }
                 fops_put(old_fops);
                 dprintk("result=%d\n", err);
                 return err;
	}
         dprintk(KERN_DEBUG "dvb_device_open: result=ENODEV\n");
	return -ENODEV;
}

This gives output like this in normal operation:
Jan  6 11:15:18 bigred kernel: dvb_device_open: i_rdev=d400004
dvbdev=0xcfff41e0 fops=dvb_demux_fops+0x0/0xffff81e0 [dvb_core]
file=c0505560 f_op=dvb_device_fops+0x0/0xffff8280 [dvb_core] f_flags=802
private_data=0
Jan  6 11:15:18 bigred kernel: try_module_get(budget_ci): cpu=0 state=16
count=1 ret=1
Jan  6 11:15:18 bigred kernel: dvb_device_open: 
open=dvb_demux_open+0x0/0x110 [dvb_core] result=0

3. The crash now looks like this:

Jan  6 11:15:19 bigred kernel: dvb_device_open: i_rdev=d400003 
dvbdev=0xcfff4620 fops=dvb_frontend_fops+0x0/0xffff7ca0 [dvb_core] 
file=c0a4bb00 f_op=dvb_device_fops+0x0/0xffff8280 [dvb_core] f_flags=0 
private_data=0
Jan  6 11:15:19 bigred kernel: Unable to handle kernel paging request at 
virtual address d0a97580
Jan  6 11:15:19 bigred kernel:  printing eip:
Jan  6 11:15:19 bigred kernel: d0aa20d8
Jan  6 11:15:19 bigred kernel: *pde = 0ffcb067
Jan  6 11:15:19 bigred kernel: *pte = 00000000
Jan  6 11:15:19 bigred kernel: Oops: 0000 [#1]

4. Further digging with a disassembler into the module suggests that the 
crash happens at one of the statements marked "see below". The debug 
output, however, shows that the "file" pointer is most likely _not_ 
corrupted. This leaves not many possible reasons.

I've not exactly understood what the compiler makes of these statements 
though, so I tried another compiler, and voila - it works.

----

So can some kernel guru perhaps look into what GCC 3.3.3 makes of 
fops_get()? Perhaps we have a compiler bug or some sort of unfortunate 
interaction with the nontrivial macroized code...

Thanks for your help anyway,

Olaf


           reply	other threads:[~2005-01-06 16:28 UTC|newest]

Thread overview: expand[flat|nested]  mbox.gz  Atom feed
 [parent not found: <200501051404.43182.adq_dvb@lidskialf.net>]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=41DD66CC.9070805@bigred.inka.de \
    --to=olaf@bigred.inka.de \
    --cc=adq_dvb@lidskialf.net \
    --cc=linux-dvb@linuxtv.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.