All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Lear <matt@bubblegen.co.uk>
To: linux-mtd@lists.infradead.org
Cc: rpurdie@openedhand.com
Subject: mtdoops and non pre-emptible kernel
Date: Wed, 26 Aug 2009 18:41:35 +0100	[thread overview]
Message-ID: <4A9573CF.8030105@bubblegen.co.uk> (raw)

[-- Attachment #1: Type: text/plain, Size: 3533 bytes --]

Hello,

I'm trying to use the mtd oops feature on a non pre-emptible m68k
coldfire Linux kernel. Problem is, there is nothing being written to
flash upon a kernel panic. I'm passing the correct syntax on the command
line and I can see the kernel messages indicating that everything is ok, ie:

/ # dmesg | grep -i mtd
[    0.000000] Kernel command line: console=ttyS0,115200 ip=dhcp
root=/dev/nfs nfsroot=192.168.0.2:/home/matt/nfs/evb/rootfs/ rw
mtdparts=physmap-flash.0:4M@0x80000(kernel)ro,5M@0x480000(r
amdisk),-@0x980000(writeable) console=ttyMTD2
[    0.336920] console [ttyMTD2] enabled
[    0.933655] 3 cmdlinepart partitions found on MTD device physmap-flash.0
[    0.940745] Creating 3 MTD partitions on "physmap-flash.0":
[    0.951893] mtd: Giving out device 0 to kernel
[    0.965760] mtd: Giving out device 1 to ramdisk
[    0.979124] mtd: Giving out device 2 to writeable
[    0.993942] mtdoops: Ready 8, 9 (no erase)
[    0.993979] mtdoops: Attached to MTD device 2

The issue appears to be that the call to schedule_work() in
mtdoops_console_sync() does not result in mtdoops_workfunc_write() being
invoked to perform the flash write.

I understand that there is only a very small window in which to actually
flush the buffer to flash (involving a spinlock and testing
oops_in_progress). However, from what I can tell, on a non pre-emptible
kernel, after panic() does it's business of calling bust_spinlocks(),
which calls console_unblank(), which calls mtdoops_console_sync(), which
calls schedule_work(), there is no way [certainly that I can see] that
the system can context switch to the worker thread in order to invoke
the routine that actually writes to flash.

The only way I have been able to get the flash to be written to upon
panic is to make the following change:

diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
index 1a6b3be..2d734e2 100644
--- a/drivers/mtd/mtdoops.c
+++ b/drivers/mtd/mtdoops.c
@@ -335,7 +335,7 @@ static void mtdoops_console_sync(void)
                /* Interrupt context, we're going to panic so try and log */
                mtdoops_write(cxt, 1);
        else
-               schedule_work(&cxt->work_write);
+               mtdoops_write(cxt, 0);
 }

 static void

I can pull out the logs just fine in user space using oopslog, courtesy
of Mr Purdie.

I can replicate the same situation (worker thread not executing the
registered scheduled work routine) on my system with a simple kernel
module (attached). Without the call to schedule, the system does not
panic. In the case of the attached example, this is not surprising since
there is nothing to force a context switch. The kernel sits in the loop
forever and will warn about a soft lock up (if this feature is enabled).

I have tried invoking schedule() immediately after schedule_work() in
mtdoops_console_sync(). However this still results in flash not being
written to when there is a panic. I realise that now there are of course
other factors at play which could explain why the flash never gets
written to, (specifically related to scheduling, eg thread time slices,
quantums etc), but I wanted to point out that there certainly appears to
be a couple of cases in mtdoops.c where there should be calls to
schedule() after calls to schedule_work() - only there aren't.

I don't mean to criticise the code :-) I'm an avid user of open source,
but I'd be interested if the mtd oops feature works reliably on other
non pre-emptive kernels.

Thoughts? Any feedback much appreciated.

Best regards,
--  Matt

[-- Attachment #2: work.c --]
[-- Type: text/x-csrc, Size: 757 bytes --]

#include <linux/init.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/delay.h>
#include <linux/sched.h>

MODULE_LICENSE("foo");

static struct work_struct mywork;

static void mywork_func(struct work_struct *work)
{
   panic("Adios muchachos");
}

static int myinit(void)
{
   int i;
   printk(KERN_ALERT "myinit ->\n");

   INIT_WORK(&mywork, mywork_func);

   schedule_work(&mywork);
   schedule();

   /* This loop will hang non-premptible kernels and the worker func above
    * will not be executed without the above call to schedule. */
   for (i = 0;;) {
      mdelay(1);
      i++;
   }

   return 0;
}

static void myexit(void)
{
   printk(KERN_ALERT "<- myinit\n");
   return;
}

module_init(myinit);
module_exit(myexit);

             reply	other threads:[~2009-08-26 17:41 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-08-26 17:41 Matthew Lear [this message]
2009-08-26 21:53 ` mtdoops and non pre-emptible kernel Richard Purdie
2009-08-27  8:59   ` Matthew Lear
2009-08-27 10:06     ` Richard Purdie
2009-08-27 10:30       ` Matthew Lear
2009-08-27 15:44         ` Richard Purdie
2009-08-27 16:20           ` Matthew Lear
2009-09-01  9:55             ` Matthew Lear

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=4A9573CF.8030105@bubblegen.co.uk \
    --to=matt@bubblegen.co.uk \
    --cc=linux-mtd@lists.infradead.org \
    --cc=rpurdie@openedhand.com \
    /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.