From: Mike Anderson <andmike@us.ibm.com>
To: Andrew Morton <akpm@digeo.com>
Cc: Andreas Boman <aboman@nerdfest.org>,
"linux-scsi@vger.kernel.org" <linux-scsi@vger.kernel.org>,
linux-kernel@vger.kernel.org, dougg@gear.torque.net
Subject: Re: 2.4.39 "Sleeping function called from illegal context at slab.c:1374"
Date: Wed, 2 Oct 2002 09:24:43 -0700 [thread overview]
Message-ID: <20021002162443.GA1317@beaverton.ibm.com> (raw)
In-Reply-To: <3D9A207A.14BFF440@digeo.com>
Andrew Morton [akpm@digeo.com] wrote:
> That is known - sg_init() is blatantly calling vmalloc under
> write_lock_irqsave().
I had not already seen a patch for this.
During Douglas Gilbert's time-off he connects when he can so it maybe a
bit until he can address this.
In the interim a quick patch below should fix the problem, and still
provide for safe additions.
I have done just minor testing on 2.5.40 using the sg_utils.
-andmike
--
Michael Anderson
andmike@us.ibm.com
sg.c | 48 +++++++++++++++++++++++++++++++++---------------
1 files changed, 33 insertions(+), 15 deletions(-)
diff -Nru a/drivers/scsi/sg.c b/drivers/scsi/sg.c
--- a/drivers/scsi/sg.c Wed Oct 2 09:00:41 2002
+++ b/drivers/scsi/sg.c Wed Oct 2 09:00:41 2002
@@ -1354,11 +1354,29 @@
{
static int sg_registered = 0;
unsigned long iflags;
+ int tmp_dev_max;
+ Sg_device **tmp_da;
if ((sg_template.dev_noticed == 0) || sg_dev_arr)
return 0;
+ SCSI_LOG_TIMEOUT(3, printk("sg_init\n"));
+
+ write_lock_irqsave(&sg_dev_arr_lock, iflags);
+ tmp_dev_max = sg_template.dev_noticed + SG_DEV_ARR_LUMP;
+ write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
+
+ tmp_da = (Sg_device **)vmalloc(
+ tmp_dev_max * sizeof(Sg_device *));
+ if (NULL == tmp_da) {
+ printk(KERN_ERR "sg_init: no space for sg_dev_arr\n");
+ return 1;
+ }
+ memset(tmp_da, 0, tmp_dev_max * sizeof (Sg_device *));
write_lock_irqsave(&sg_dev_arr_lock, iflags);
+ sg_template.dev_max = tmp_dev_max;
+ sg_dev_arr = tmp_da;
+
if (!sg_registered) {
if (register_chrdev(SCSI_GENERIC_MAJOR, "sg", &sg_fops)) {
printk(KERN_ERR
@@ -1370,16 +1388,6 @@
sg_registered++;
}
- SCSI_LOG_TIMEOUT(3, printk("sg_init\n"));
- sg_template.dev_max = sg_template.dev_noticed + SG_DEV_ARR_LUMP;
- sg_dev_arr = (Sg_device **)vmalloc(
- sg_template.dev_max * sizeof(Sg_device *));
- if (NULL == sg_dev_arr) {
- printk(KERN_ERR "sg_init: no space for sg_dev_arr\n");
- write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
- return 1;
- }
- memset(sg_dev_arr, 0, sg_template.dev_max * sizeof (Sg_device *));
write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
#ifdef CONFIG_PROC_FS
sg_proc_init();
@@ -1430,7 +1438,7 @@
static int
sg_attach(Scsi_Device * scsidp)
{
- Sg_device *sdp;
+ Sg_device *sdp = NULL;
unsigned long iflags;
int k;
@@ -1439,15 +1447,16 @@
Sg_device **tmp_da;
int tmp_dev_max = sg_template.nr_dev + SG_DEV_ARR_LUMP;
+ write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
tmp_da = (Sg_device **)vmalloc(
tmp_dev_max * sizeof(Sg_device *));
if (NULL == tmp_da) {
scsidp->attached--;
- write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
printk(KERN_ERR
"sg_attach: device array cannot be resized\n");
return 1;
}
+ write_lock_irqsave(&sg_dev_arr_lock, iflags);
memset(tmp_da, 0, tmp_dev_max * sizeof (Sg_device *));
memcpy(tmp_da, sg_dev_arr,
sg_template.dev_max * sizeof (Sg_device *));
@@ -1456,6 +1465,7 @@
sg_template.dev_max = tmp_dev_max;
}
+find_empty_slot:
for (k = 0; k < sg_template.dev_max; k++)
if (!sg_dev_arr[k])
break;
@@ -1467,11 +1477,19 @@
" type=%d, minor number exceed %d\n",
scsidp->host->host_no, scsidp->channel, scsidp->id,
scsidp->lun, scsidp->type, SG_MAX_DEVS_MASK);
+ if (NULL != sdp)
+ vfree((char *) sdp);
return 1;
}
- if (k < sg_template.dev_max)
- sdp = (Sg_device *)vmalloc(sizeof(Sg_device));
- else
+ if (k < sg_template.dev_max) {
+ if (NULL == sdp) {
+ write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
+ sdp = (Sg_device *)vmalloc(sizeof(Sg_device));
+ write_lock_irqsave(&sg_dev_arr_lock, iflags);
+ if (!sg_dev_arr[k])
+ goto find_empty_slot;
+ }
+ } else
sdp = NULL;
if (NULL == sdp) {
scsidp->attached--;
next prev parent reply other threads:[~2002-10-02 16:24 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <3D99885B.533C320D@aitel.hist.no>
[not found] ` <3D99EF62.3A3E6932@digeo.com>
[not found] ` <20021001215907.GA8273@midgaard.us>
2002-10-01 22:23 ` 2.4.39 "Sleeping function called from illegal context at slab.c:1374" Andrew Morton
2002-10-02 16:24 ` Mike Anderson [this message]
2002-10-02 18:44 ` Andreas Boman
2002-10-02 19:31 ` Mike Anderson
2002-10-02 21:21 ` Mike Anderson
2002-10-02 23:53 ` Andreas Boman
2002-10-03 17:17 ` Mike Anderson
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=20021002162443.GA1317@beaverton.ibm.com \
--to=andmike@us.ibm.com \
--cc=aboman@nerdfest.org \
--cc=akpm@digeo.com \
--cc=dougg@gear.torque.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@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