All of lore.kernel.org
 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 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.