linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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;
 }

  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).