mirror of https://lore.kernel.org/lkml/
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome