From: Douglas Gilbert <dougg@torque.net>
To: Nishanth Aravamudan <nacc@us.ibm.com>
Cc: linux-scsi@vger.kernel.org
Subject: Re: scsi_debug issues
Date: Sat, 16 Oct 2004 16:51:49 +1000 [thread overview]
Message-ID: <4170C505.3000805@torque.net> (raw)
In-Reply-To: <20041015190154.GA3073@us.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 1951 bytes --]
Nishanth Aravamudan wrote:
> Hi,
>
> At the recommendation of Pat Mansfield, I'm posting this issue to
> linux-scsi. I have run into a big problem with the scsi_debug driver
> which is causing my machine to hang.
>
> I was finally able to get a large number (10000) of scsi_debug disks via
> modprobe (no partitioning, no mounting, no fs), so I decided to go ahead
> and try to continue the experiment. I found that I was not able to ls in
> a mounted directory from one of the scsi_debug disks. In the chance that
> it was somehow due to the high number of disks present, I tried just
>
> modprobe scsi_debug
>
> so that I would only get one disk. I then ran these commands [0]. I did
> not set the SCSI logging on until the last moment, after I synced the
> existent SCSI disks in the machine (there are two actual SCSI disks)
> [1]. I found that the ls command never fails to hang (although sometimes
> it will not hang immediately, I have to
>
> cd lost+found
>
> first. Interestingly, if the machine does not have highmem (i.e. less
> than 896 MB of RAM) or the kernel is booted with mem=800 (or some other
> number less than 896), the problem dissappears. I had to put the check
> in my patch in for the NULL dereference, as it would cause a
> segmentation fault otherwise. I'm guessing that is where the problem may
> be, as the NULL-check was not there before (an assumption that it
> (scatg2virt) would always work?).
Nishanth,
So this problem seems related to highmem.
The attachment is against the current scsi_debug driver
(at least in lk 2.6.9-rc4). It uses dma_map_sg() and friends
together with phys_to_virt() which comes highly recommended:
"in almost all conceivable cases a device driver should not be
using this function" :-) Could you try the patch.
Perhaps others my be able to answer this: is setting
scsi_host_template::dma_boundary (to some figure other
than 0xffffffff) going to help in this case?
Doug Gilbert
[-- Attachment #2: sdebug2681dma1.diff --]
[-- Type: text/x-patch, Size: 4095 bytes --]
--- linux/drivers/scsi/scsi_debug.c 2004-08-14 21:12:43.000000000 +1000
+++ linux/drivers/scsi/scsi_debug.c2681dma1 2004-10-16 16:22:34.330229976 +1000
@@ -262,16 +262,6 @@
static struct device pseudo_primary;
static struct bus_type pseudo_lld_bus;
-static unsigned char * scatg2virt(const struct scatterlist * sclp)
-{
- if (NULL == sclp)
- return NULL;
- else if (sclp->page)
- return (unsigned char *)page_address(sclp->page) +
- sclp->offset;
- else
- return NULL;
-}
static
int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
@@ -286,6 +276,7 @@
struct sdebug_dev_info * devip = NULL;
unsigned char * sbuff;
int inj_recovered = 0;
+ int num_elems = 0;
if (done == NULL)
return 0; /* assume mid level reprocessing command */
@@ -294,8 +285,12 @@
struct scatterlist *sgpnt = (struct scatterlist *)
SCpnt->request_buffer;
- buff = scatg2virt(&sgpnt[0]);
- bufflen = sgpnt[0].length;
+ num_elems = dma_map_sg(NULL, sgpnt, SCpnt->use_sg,
+ SCpnt->sc_data_direction);
+ buff = phys_to_virt(sg_dma_address(&sgpnt[0]));
+ bufflen = sg_dma_len(&sgpnt[0]);
+ dma_unmap_sg(NULL, sgpnt, SCpnt->use_sg,
+ SCpnt->sc_data_direction);
/* READ and WRITE process scatterlist themselves */
}
else
@@ -778,6 +773,7 @@
struct scatterlist *sgpnt = NULL;
int bufflen = SCpnt->request_bufflen;
unsigned long iflags;
+ int num_elems = 0;
if (upper_blk || (block + num > sdebug_capacity)) {
mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE,
@@ -799,9 +795,11 @@
block, bufflen); */
if (SCpnt->use_sg) {
sgcount = 0;
- sgpnt = (struct scatterlist *) buff;
- buff = scatg2virt(&sgpnt[sgcount]);
- bufflen = sgpnt[sgcount].length;
+ sgpnt = (struct scatterlist *)buff;
+ num_elems = dma_map_sg(NULL, sgpnt, SCpnt->use_sg,
+ SCpnt->sc_data_direction);
+ buff = phys_to_virt(sg_dma_address(&sgpnt[0]));
+ bufflen = sg_dma_len(&sgpnt[0]);
}
do {
memcpy(buff, fake_storep + (block * SECT_SIZE), bufflen);
@@ -809,14 +807,18 @@
if (SCpnt->use_sg) {
block += bufflen >> POW2_SECT_SIZE;
sgcount++;
- if (nbytes) {
- buff = scatg2virt(&sgpnt[sgcount]);
- bufflen = sgpnt[sgcount].length;
+ if (nbytes > 0) {
+ buff = phys_to_virt(
+ sg_dma_address(&sgpnt[sgcount]));
+ bufflen = sg_dma_len(&sgpnt[sgcount]);
}
} else if (nbytes > 0)
printk(KERN_WARNING "scsi_debug:resp_read: unexpected "
"nbytes=%d\n", nbytes);
- } while (nbytes);
+ } while (nbytes > 0);
+ if (SCpnt->use_sg)
+ dma_unmap_sg(NULL, sgpnt, SCpnt->use_sg,
+ SCpnt->sc_data_direction);
read_unlock_irqrestore(&atomic_rw, iflags);
return 0;
}
@@ -829,6 +831,7 @@
struct scatterlist *sgpnt = NULL;
int bufflen = SCpnt->request_bufflen;
unsigned long iflags;
+ int num_elems = 0;
if (upper_blk || (block + num > sdebug_capacity)) {
mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE,
@@ -842,8 +845,10 @@
if (SCpnt->use_sg) {
sgcount = 0;
sgpnt = (struct scatterlist *) buff;
- buff = scatg2virt(&sgpnt[sgcount]);
- bufflen = sgpnt[sgcount].length;
+ num_elems = dma_map_sg(NULL, sgpnt, SCpnt->use_sg,
+ SCpnt->sc_data_direction);
+ buff = phys_to_virt(sg_dma_address(&sgpnt[0]));
+ bufflen = sg_dma_len(&sgpnt[0]);
}
do {
memcpy(fake_storep + (block * SECT_SIZE), buff, bufflen);
@@ -852,14 +857,18 @@
if (SCpnt->use_sg) {
block += bufflen >> POW2_SECT_SIZE;
sgcount++;
- if (nbytes) {
- buff = scatg2virt(&sgpnt[sgcount]);
- bufflen = sgpnt[sgcount].length;
+ if (nbytes > 0) {
+ buff = phys_to_virt(
+ sg_dma_address(&sgpnt[sgcount]));
+ bufflen = sg_dma_len(&sgpnt[sgcount]);
}
} else if (nbytes > 0)
printk(KERN_WARNING "scsi_debug:resp_write: "
"unexpected nbytes=%d\n", nbytes);
- } while (nbytes);
+ } while (nbytes > 0);
+ if (SCpnt->use_sg)
+ dma_unmap_sg(NULL, sgpnt, SCpnt->use_sg,
+ SCpnt->sc_data_direction);
write_unlock_irqrestore(&atomic_rw, iflags);
return 0;
}
next prev parent reply other threads:[~2004-10-16 6:52 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-10-15 19:01 scsi_debug issues Nishanth Aravamudan
2004-10-16 6:51 ` Douglas Gilbert [this message]
2004-10-16 10:50 ` Christoph Hellwig
2004-10-16 13:12 ` James Bottomley
2004-10-18 13:44 ` [PATCH] scsi_debug [was: scsi_debug issues] Douglas Gilbert
2004-10-18 18:37 ` Nishanth Aravamudan
2004-10-18 22:05 ` Douglas Gilbert
2004-10-18 23:23 ` Nishanth Aravamudan
2004-10-19 6:57 ` Douglas Gilbert
2004-10-21 21:36 ` Nishanth Aravamudan
2004-10-22 10:04 ` Jens Axboe
2004-10-22 10:02 ` Jens Axboe
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=4170C505.3000805@torque.net \
--to=dougg@torque.net \
--cc=linux-scsi@vger.kernel.org \
--cc=nacc@us.ibm.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).