Skip to contentSkip to conversation

Chaining sg lists for big IO commands v5

PATCH In review Jens Axboe 5 participants 34 messages May 11, 2007 – May 25, 2007

Subsystems (34)
SCSI USB PowerPC Block layer +30 more subsystems
lore
Share & tools
lore

Jens Axboe

author
#0 lore raw

PATCH 1/1 Chaining sg lists for big IO commands v5

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Changes:

- Fixed a bug with freeing scatterlist tables, would crash the box.
- Fixed a bug with freeing scatterlist tables in case of OOM.
- Improved x86-64 pci-gart support from Benny Halevy
- Fixed swiotlb, it needs to be updated for sg chaining as well of course. I had missed that one.
- Updated a slew of other drivers (usb storage, ide, sg, IB).

This one has actually been tested, it works fine for me. The only performance numbers I attempted to do was with scsi_debug. It is about 10% faster with larger commands for an O_DIRECT read test case. The improvement comes from issuing 75% fewer commands.

Patch is against current git.

 arch/ia64/hp/sim/simscsi.c                |   23 +-
 arch/x86_64/kernel/pci-calgary.c          |   25 +-
 arch/x86_64/kernel/pci-gart.c             |   60 +++--
 arch/x86_64/kernel/pci-nommu.c            |    5 
 block/ll_rw_blk.c                         |   42 +++-
 crypto/digest.c                           |    2 
 crypto/scatterwalk.c                      |    2 
 crypto/scatterwalk.h                      |    2 
 drivers/ata/libata-core.c                 |   30 +-
 drivers/ide/cris/ide-cris.c               |    3 
 drivers/ide/ide-dma.c                     |    2 
 drivers/ide/ide-taskfile.c                |   17 +
 drivers/ide/mips/au1xxx-ide.c             |    2 
 drivers/ide/pci/sgiioc4.c                 |    2 
 drivers/ide/ppc/pmac.c                    |    2 
 drivers/infiniband/hw/ipath/ipath_dma.c   |    9 
 drivers/infiniband/ulp/iser/iser_memory.c |   75 +++----
 drivers/infiniband/ulp/srp/ib_srp.c       |   22 +-
 drivers/message/fusion/mptscsih.c         |    4 
 drivers/scsi/3w-9xxx.c                    |    8 
 drivers/scsi/3w-xxxx.c                    |    8 
 drivers/scsi/53c700.c                     |   16 -
 drivers/scsi/BusLogic.c                   |    7 
 drivers/scsi/NCR53c406a.c                 |   18 -
 drivers/scsi/a100u2w.c                    |    9 
 drivers/scsi/aacraid/aachba.c             |   29 +-
 drivers/scsi/advansys.c                   |   21 --
 drivers/scsi/aha1542.c                    |   21 --
 drivers/scsi/aha1740.c                    |    8 
 drivers/scsi/aic7xxx/aic79xx_osm.c        |    3 
 drivers/scsi/aic7xxx/aic7xxx_osm.c        |   12 -
 drivers/scsi/aic94xx/aic94xx_task.c       |    6 
 drivers/scsi/arcmsr/arcmsr_hba.c          |   11 -
 drivers/scsi/dc395x.c                     |    7 
 drivers/scsi/dpt_i2o.c                    |   13 -
 drivers/scsi/eata.c                       |    8 
 drivers/scsi/esp_scsi.c                   |    5 
 drivers/scsi/gdth.c                       |   45 ++--
 drivers/scsi/hptiop.c                     |    8 
 drivers/scsi/ibmmca.c                     |   11 -
 drivers/scsi/ibmvscsi/ibmvscsi.c          |    4 
 drivers/scsi/ide-scsi.c                   |   31 +--
 drivers/scsi/initio.c                     |   12 -
 drivers/scsi/ipr.c                        |    9 
 drivers/scsi/ips.c                        |   74 +++----
 drivers/scsi/iscsi_tcp.c                  |   43 ++--
 drivers/scsi/jazz_esp.c                   |   27 +-
 drivers/scsi/lpfc/lpfc_scsi.c             |    9 
 drivers/scsi/mac53c94.c                   |    9 
 drivers/scsi/megaraid.c                   |   13 -
 drivers/scsi/megaraid/megaraid_mbox.c     |    7 
 drivers/scsi/megaraid/megaraid_sas.c      |   16 -
 drivers/scsi/mesh.c                       |   12 -
 drivers/scsi/ncr53c8xx.c                  |    7 
 drivers/scsi/nsp32.c                      |    9 
 drivers/scsi/pcmcia/sym53c500_cs.c        |   18 -
 drivers/scsi/qla1280.c                    |   66 +++---
 drivers/scsi/qla2xxx/qla_iocb.c           |    9 
 drivers/scsi/qla4xxx/ql4_iocb.c           |    8 
 drivers/scsi/qlogicfas408.c               |    9 
 drivers/scsi/qlogicpti.c                  |   15 -
 drivers/scsi/scsi_debug.c                 |   29 +-
 drivers/scsi/scsi_lib.c                   |  227 ++++++++++++++++------
 drivers/scsi/scsi_tgt_lib.c               |    4 
 drivers/scsi/sg.c                         |   16 -
 drivers/scsi/sym53c416.c                  |    9 
 drivers/scsi/sym53c8xx_2/sym_glue.c       |    7 
 drivers/scsi/u14-34f.c                    |   10 
 drivers/scsi/ultrastor.c                  |   10 
 drivers/scsi/wd7000.c                     |    7 
 drivers/usb/storage/alauda.c              |   16 -
 drivers/usb/storage/datafab.c             |   10 
 drivers/usb/storage/jumpshot.c            |   10 
 drivers/usb/storage/protocol.c            |   20 +
 drivers/usb/storage/protocol.h            |    2 
 drivers/usb/storage/sddr09.c              |   16 -
 drivers/usb/storage/sddr55.c              |   16 -
 drivers/usb/storage/shuttle_usbat.c       |   17 -
 include/asm-i386/dma-mapping.h            |   13 -
 include/asm-i386/scatterlist.h            |    2 
 include/asm-x86_64/dma-mapping.h          |    3 
 include/asm-x86_64/scatterlist.h          |    2 
 include/linux/i2o.h                       |    2 
 include/linux/ide.h                       |    2 
 include/linux/libata.h                    |   16 -
 include/linux/scatterlist.h               |   57 +++++
 include/scsi/scsi.h                       |    7 
 include/scsi/scsi_cmnd.h                  |    3 
 lib/swiotlb.c                             |   19 +
 89 files changed, 917 insertions(+), 645 deletions(-)
arch/ia64/hp/sim/simscsi.c +14 -9
index bb87682..291e7f4 100644
@@ -173,7 +173,7 @@ simscsi_sg_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset)
 			return;
 		}
 		offset +=  sl->length;
-		sl++;
+		sl = sg_next(sl);
 		list_len--;
 	}
 	sc->result = GOOD;
@@ -239,18 +239,23 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode)
 static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
 {
 
-	int scatterlen = sc->use_sg;
-	struct scatterlist *slp;
+	int scatterlen = sc->use_sg, i;
+	struct scatterlist *slp, *sg;
 
 	if (scatterlen == 0)
 		memcpy(sc->request_buffer, buf, len);
-	else for (slp = (struct scatterlist *)sc->request_buffer;
-		  scatterlen-- > 0 && len > 0; slp++) {
-		unsigned thislen = min(len, slp->length);
+	else {
+		slp = sc->request_buffer;
+		for_each_sg(slp, sg, scatterlen, i) {
+			unsigned thislen;
 
-		memcpy(page_address(slp->page) + slp->offset, buf, thislen);
-		slp++;
-		len -= thislen;
+			if (len <= 0)
+				break;
+
+			thislen = min(len, slp->length);
+			memcpy(page_address(sg->page) + sg->offset, buf, thislen);
+			len -= thislen;
+		}
 	}
 }
 
arch/x86_64/kernel/pci-calgary.c +14 -11
index 5bd20b5..c472b14 100644
@@ -35,6 +35,7 @@
 #include <linux/pci_ids.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/scatterlist.h>
 #include <asm/proto.h>
 #include <asm/calgary.h>
 #include <asm/tce.h>
@@ -341,17 +342,19 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
 static void __calgary_unmap_sg(struct iommu_table *tbl,
 	struct scatterlist *sglist, int nelems, int direction)
 {
-	while (nelems--) {
+	struct scatterlist *s;
+	int i;
+
+	for_each_sg(sglist, s, nelems, i) {
 		unsigned int npages;
-		dma_addr_t dma = sglist->dma_address;
-		unsigned int dmalen = sglist->dma_length;
+		dma_addr_t dma = s->dma_address;
+		unsigned int dmalen = s->dma_length;
 
 		if (dmalen == 0)
 			break;
 
 		npages = num_dma_pages(dma, dmalen);
 		__iommu_free(tbl, dma, npages);
-		sglist++;
 	}
 }
 
@@ -374,10 +377,10 @@ void calgary_unmap_sg(struct device *dev, struct scatterlist *sglist,
 static int calgary_nontranslate_map_sg(struct device* dev,
 	struct scatterlist *sg, int nelems, int direction)
 {
+	struct scatterlist *s;
 	int i;
 
- 	for (i = 0; i < nelems; i++ ) {
-		struct scatterlist *s = &sg[i];
+	for_each_sg(sg, s, nelems, i) {
 		BUG_ON(!s->page);
 		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
 		s->dma_length = s->length;
@@ -389,6 +392,7 @@ int calgary_map_sg(struct device *dev, struct scatterlist *sg,
 	int nelems, int direction)
 {
 	struct iommu_table *tbl = to_pci_dev(dev)->bus->self->sysdata;
+	struct scatterlist *s;
 	unsigned long flags;
 	unsigned long vaddr;
 	unsigned int npages;
@@ -400,8 +404,7 @@ int calgary_map_sg(struct device *dev, struct scatterlist *sg,
 
 	spin_lock_irqsave(&tbl->it_lock, flags);
 
-	for (i = 0; i < nelems; i++ ) {
-		struct scatterlist *s = &sg[i];
+	for_each_sg(sg, s, nelems, i) {
 		BUG_ON(!s->page);
 
 		vaddr = (unsigned long)page_address(s->page) + s->offset;
@@ -428,9 +431,9 @@ int calgary_map_sg(struct device *dev, struct scatterlist *sg,
 	return nelems;
 error:
 	__calgary_unmap_sg(tbl, sg, nelems, direction);
-	for (i = 0; i < nelems; i++) {
-		sg[i].dma_address = bad_dma_address;
-		sg[i].dma_length = 0;
+	for_each_sg(sg, s, nelems, i) {
+		s->dma_address = bad_dma_address;
+		s->dma_length = 0;
 	}
 	spin_unlock_irqrestore(&tbl->it_lock, flags);
 	return 0;
arch/x86_64/kernel/pci-gart.c +32 -28

153 lines not on this page · raw message

arch/x86_64/kernel/pci-nommu.c +3 -2
index 6dade0c..24c9faf 100644
@@ -5,6 +5,7 @@
 #include <linux/pci.h>
 #include <linux/string.h>
 #include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
 
 #include <asm/proto.h>
 #include <asm/processor.h>
@@ -57,10 +58,10 @@ void nommu_unmap_single(struct device *dev, dma_addr_t addr,size_t size,
 int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
 	       int nents, int direction)
 {
+	struct scatterlist *s;
 	int i;
 
- 	for (i = 0; i < nents; i++ ) {
-		struct scatterlist *s = &sg[i];
+	for_each_sg(sg, s, nents, i) {
 		BUG_ON(!s->page);
 		s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
 		if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
block/ll_rw_blk.c +35 -7

96 lines not on this page · raw message

crypto/digest.c +1 -1
index 1bf7414..e56de67 100644
@@ -77,7 +77,7 @@ static int update2(struct hash_desc *desc,
 
 		if (!nbytes)
 			break;
-		sg = sg_next(sg);
+		sg = scatterwalk_sg_next(sg);
 	}
 
 	return 0;
crypto/scatterwalk.c +1 -1
index 81afd17..2e51f82 100644
@@ -70,7 +70,7 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
 		walk->offset += PAGE_SIZE - 1;
 		walk->offset &= PAGE_MASK;
 		if (walk->offset >= walk->sg->offset + walk->sg->length)
-			scatterwalk_start(walk, sg_next(walk->sg));
+			scatterwalk_start(walk, scatterwalk_sg_next(walk->sg));
 	}
 }
 
crypto/scatterwalk.h +1 -1
index f1592cc..e049c62 100644
@@ -20,7 +20,7 @@
 
 #include "internal.h"
 
-static inline struct scatterlist *sg_next(struct scatterlist *sg)
+static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
 {
 	return (++sg)->length ? sg : (void *)sg->page;
 }
drivers/ata/libata-core.c +16 -14
index 4595d1f..fabb1f4 100644
@@ -1370,7 +1370,7 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
  */
 unsigned ata_exec_internal_sg(struct ata_device *dev,
 			      struct ata_taskfile *tf, const u8 *cdb,
-			      int dma_dir, struct scatterlist *sg,
+			      int dma_dir, struct scatterlist *sgl,
 			      unsigned int n_elem)
 {
 	struct ata_port *ap = dev->ap;
@@ -1428,11 +1428,12 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
 	qc->dma_dir = dma_dir;
 	if (dma_dir != DMA_NONE) {
 		unsigned int i, buflen = 0;
+		struct scatterlist *sg;
 
-		for (i = 0; i < n_elem; i++)
-			buflen += sg[i].length;
+		for_each_sg(sgl, sg, n_elem, i)
+			buflen += sg->length;
 
-		ata_sg_init(qc, sg, n_elem);
+		ata_sg_init(qc, sgl, n_elem);
 		qc->nbytes = buflen;
 	}
 
@@ -3982,7 +3983,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
 		if (qc->n_elem)
 			dma_unmap_sg(ap->dev, sg, qc->n_elem, dir);
 		/* restore last sg */
-		sg[qc->orig_n_elem - 1].length += qc->pad_len;
+		sg_last(sg, qc->orig_n_elem)->length += qc->pad_len;
 		if (pad_buf) {
 			struct scatterlist *psg = &qc->pad_sgent;
 			void *addr = kmap_atomic(psg->page, KM_IRQ0);
@@ -4141,6 +4142,7 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
 	qc->orig_n_elem = 1;
 	qc->buf_virt = buf;
 	qc->nbytes = buflen;
+	qc->cursg = qc->__sg;
 
 	sg_init_one(&qc->sgent, buf, buflen);
 }
@@ -4166,6 +4168,7 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
 	qc->__sg = sg;
 	qc->n_elem = n_elem;
 	qc->orig_n_elem = n_elem;
+	qc->cursg = qc->__sg;
 }
 
 /**
@@ -4255,7 +4258,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
 	struct scatterlist *sg = qc->__sg;
-	struct scatterlist *lsg = &sg[qc->n_elem - 1];
+	struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
 	int n_elem, pre_n_elem, dir, trim_sg = 0;
 
 	VPRINTK("ENTER, ata%u\n", ap->print_id);
@@ -4419,7 +4422,6 @@ void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
 static void ata_pio_sector(struct ata_queued_cmd *qc)
 {
 	int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
-	struct scatterlist *sg = qc->__sg;
 	struct ata_port *ap = qc->ap;
 	struct page *page;
 	unsigned int offset;
@@ -4428,8 +4430,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
 	if (qc->curbytes == qc->nbytes - qc->sect_size)
 		ap->hsm_task_state = HSM_ST_LAST;
 
-	page = sg[qc->cursg].page;
-	offset = sg[qc->cursg].offset + qc->cursg_ofs;
+	page = qc->cursg->page;
+	offset = qc->cursg->offset + qc->cursg_ofs;
 
 	/* get the current page and offset */
 	page = nth_page(page, (offset >> PAGE_SHIFT));
@@ -4457,8 +4459,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
 	qc->curbytes += qc->sect_size;
 	qc->cursg_ofs += qc->sect_size;
 
-	if (qc->cursg_ofs == (&sg[qc->cursg])->length) {
-		qc->cursg++;
+	if (qc->cursg_ofs == qc->cursg->length) {
+		qc->cursg = sg_next(qc->cursg);
 		qc->cursg_ofs = 0;
 	}
 }
@@ -4551,7 +4553,7 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
 		ap->hsm_task_state = HSM_ST_LAST;
 
 next_sg:
-	if (unlikely(qc->cursg >= qc->n_elem)) {
+	if (unlikely(qc->cursg == sg_last(qc->__sg, qc->n_elem))) {
 		/*
 		 * The end of qc->sg is reached and the device expects
 		 * more data to transfer. In order not to overrun qc->sg
@@ -4574,7 +4576,7 @@ next_sg:
 		return;
 	}
 
-	sg = &qc->__sg[qc->cursg];
+	sg = qc->cursg;
 
 	page = sg->page;
 	offset = sg->offset + qc->cursg_ofs;
@@ -4613,7 +4615,7 @@ next_sg:
 	qc->cursg_ofs += count;
 
 	if (qc->cursg_ofs == sg->length) {
-		qc->cursg++;
+		qc->cursg = sg_next(qc->cursg);
 		qc->cursg_ofs = 0;
 	}
 
drivers/ide/cris/ide-cris.c +2 -1
index c04cb25..2e286fa 100644
@@ -951,7 +951,8 @@ static int cris_ide_build_dmatable (ide_drive_t *drive)
 		/* group sequential buffers into one large buffer */
 		addr = page_to_phys(sg->page) + sg->offset;
 		size = sg_dma_len(sg);
-		while (sg++, --i) {
+		while (--i) {
+			sg = sg_next(sg);
 			if ((addr + size) != page_to_phys(sg->page) + sg->offset)
 				break;
 			size += sg_dma_len(sg);
drivers/ide/ide-dma.c +1 -1
index 5fe8519..9485491 100644
@@ -292,7 +292,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
 			}
 		}
 
-		sg++;
+		sg = sg_next(sg);
 		i--;
 	}
 
drivers/ide/ide-taskfile.c +13 -4
index 30175c7..412ba5e 100644
@@ -259,6 +259,7 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	struct scatterlist *sg = hwif->sg_table;
+	struct scatterlist *cursg = hwif->cursg;
 	struct page *page;
 #ifdef CONFIG_HIGHMEM
 	unsigned long flags;
@@ -266,8 +267,14 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
 	unsigned int offset;
 	u8 *buf;
 
-	page = sg[hwif->cursg].page;
-	offset = sg[hwif->cursg].offset + hwif->cursg_ofs * SECTOR_SIZE;
+	cursg = hwif->cursg;
+	if (!cursg) {
+		cursg = sg;
+		hwif->cursg = sg;
+	}
+
+	page = cursg->page;
+	offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
 
 	/* get the current page and offset */
 	page = nth_page(page, (offset >> PAGE_SHIFT));
@@ -281,8 +288,8 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
 	hwif->nleft--;
 	hwif->cursg_ofs++;
 
-	if ((hwif->cursg_ofs * SECTOR_SIZE) == sg[hwif->cursg].length) {
-		hwif->cursg++;
+	if ((hwif->cursg_ofs * SECTOR_SIZE) == cursg->length) {
+		hwif->cursg = sg_next(hwif->cursg);
 		hwif->cursg_ofs = 0;
 	}
 
@@ -363,6 +370,8 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
 
 static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
 {
+	HWIF(drive)->cursg = NULL;
+
 	if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
 		ide_task_t *task = rq->special;
 
drivers/ide/mips/au1xxx-ide.c +1 -1
index ca95e99..35b0d1e 100644
@@ -324,7 +324,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
 			cur_addr += tc;
 			cur_len -= tc;
 		}
-		sg++;
+		sg = sg_next(sg);
 		i--;
 	}
 
drivers/ide/pci/sgiioc4.c +1 -1
index d3185e2..511e734 100644
@@ -531,7 +531,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
 			}
 		}
 
-		sg++;
+		sg = sg_next(sg);
 		i--;
 	}
 
drivers/ide/ppc/pmac.c +1 -1
index 45fc36f..2a7555d 100644
@@ -1648,7 +1648,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
 			cur_len -= tc;
 			++table;
 		}
-		sg++;
+		sg = sg_next(sg);
 		i--;
 	}
 
drivers/infiniband/hw/ipath/ipath_dma.c +5 -4
index f87f003..62c87e6 100644
@@ -96,17 +96,18 @@ static void ipath_dma_unmap_page(struct ib_device *dev,
 	BUG_ON(!valid_dma_direction(direction));
 }
 
-static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sg, int nents,
-			enum dma_data_direction direction)
+static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sgl,
+			int nents, enum dma_data_direction direction)
 {
+	struct scatterlist *sg;
 	u64 addr;
 	int i;
 	int ret = nents;
 
 	BUG_ON(!valid_dma_direction(direction));
 
-	for (i = 0; i < nents; i++) {
-		addr = (u64) page_address(sg[i].page);
+	for_each_sg(sgl, sg, nents, i) {
+		addr = (u64) page_address(sg->page);
 		/* TODO: handle highmem pages */
 		if (!addr) {
 			ret = 0;
drivers/infiniband/ulp/iser/iser_memory.c +40 -35

157 lines not on this page · raw message

drivers/infiniband/ulp/srp/ib_srp.c +12 -10
index 39bf057..c31d50d 100644
@@ -595,6 +595,7 @@ static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat,
 	int ret;
 	struct srp_device *dev = target->srp_host->dev;
 	struct ib_device *ibdev = dev->dev;
+	struct scatterlist *sg;
 
 	if (!dev->fmr_pool)
 		return -ENODEV;
@@ -604,16 +605,16 @@ static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat,
 		return -EINVAL;
 
 	len = page_cnt = 0;
-	for (i = 0; i < sg_cnt; ++i) {
-		unsigned int dma_len = ib_sg_dma_len(ibdev, &scat[i]);
+	for_each_sg(scat, sg, sg_cnt, i) {
+		unsigned int dma_len = ib_sg_dma_len(ibdev, sg);
 
-		if (ib_sg_dma_address(ibdev, &scat[i]) & ~dev->fmr_page_mask) {
+		if (ib_sg_dma_address(ibdev, sg) & ~dev->fmr_page_mask) {
 			if (i > 0)
 				return -EINVAL;
 			else
 				++page_cnt;
 		}
-		if ((ib_sg_dma_address(ibdev, &scat[i]) + dma_len) &
+		if ((ib_sg_dma_address(ibdev, sg) + dma_len) &
 		    ~dev->fmr_page_mask) {
 			if (i < sg_cnt - 1)
 				return -EINVAL;
@@ -633,12 +634,12 @@ static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat,
 		return -ENOMEM;
 
 	page_cnt = 0;
-	for (i = 0; i < sg_cnt; ++i) {
-		unsigned int dma_len = ib_sg_dma_len(ibdev, &scat[i]);
+	for_each_sg(scat, sg, sg_cnt, i) {
+		unsigned int dma_len = ib_sg_dma_len(ibdev, sg);
 
 		for (j = 0; j < dma_len; j += dev->fmr_page_size)
 			dma_pages[page_cnt++] =
-				(ib_sg_dma_address(ibdev, &scat[i]) &
+				(ib_sg_dma_address(ibdev, sg) &
 				 dev->fmr_page_mask) + j;
 	}
 
@@ -724,6 +725,7 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
 		 * descriptor.
 		 */
 		struct srp_indirect_buf *buf = (void *) cmd->add_data;
+		struct scatterlist *sg;
 		u32 datalen = 0;
 		int i;
 
@@ -732,11 +734,11 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
 			sizeof (struct srp_indirect_buf) +
 			count * sizeof (struct srp_direct_buf);
 
-		for (i = 0; i < count; ++i) {
-			unsigned int dma_len = ib_sg_dma_len(ibdev, &scat[i]);
+		for_each_sg(scat, sg, count, i) {
+			unsigned int dma_len = ib_sg_dma_len(ibdev, sg);
 
 			buf->desc_list[i].va  =
-				cpu_to_be64(ib_sg_dma_address(ibdev, &scat[i]));
+				cpu_to_be64(ib_sg_dma_address(ibdev, sg));
 			buf->desc_list[i].key =
 				cpu_to_be32(dev->mr->rkey);
 			buf->desc_list[i].len = cpu_to_be32(dma_len);
drivers/message/fusion/mptscsih.c +2 -2
index fa0f776..8844167 100644
@@ -315,7 +315,7 @@ nextSGEset:
 		v2 = sg_dma_address(sg);
 		mptscsih_add_sge(psge, sgflags | thisxfer, v2);
 
-		sg++;		/* Get next SG element from the OS */
+		sg = sg_next(sg);	/* Get next SG element from the OS */
 		psge += (sizeof(u32) + sizeof(dma_addr_t));
 		sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
 		sg_done++;
@@ -336,7 +336,7 @@ nextSGEset:
 		v2 = sg_dma_address(sg);
 		mptscsih_add_sge(psge, sgflags | thisxfer, v2);
 		/*
-		sg++;
+		sg = sg_next(sg);
 		psge += (sizeof(u32) + sizeof(dma_addr_t));
 		*/
 		sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
drivers/scsi/3w-9xxx.c +4 -4
index eb766c3..293cfd2 100644
@@ -1815,7 +1815,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
 	u32 num_sectors = 0x0;
 	int i, sg_count;
 	struct scsi_cmnd *srb = NULL;
-	struct scatterlist *sglist = NULL;
+	struct scatterlist *sglist = NULL, *sg;
 	dma_addr_t buffaddr = 0x0;
 	int retval = 1;
 
@@ -1893,9 +1893,9 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
 				if (sg_count == 0)
 					goto out;
 
-				for (i = 0; i < sg_count; i++) {
-					command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(&sglist[i]));
-					command_packet->sg_list[i].length = cpu_to_le32(sg_dma_len(&sglist[i]));
+				for_each_sg(sglist, sg, sg_count, i) {
+					command_packet->sg_list[i].address = TW_CPU_TO_SGL(sg_dma_address(sg));
+					command_packet->sg_list[i].length = cpu_to_le32(sg_dma_len(sg));
 					if (command_packet->sg_list[i].address & TW_CPU_TO_SGL(TW_ALIGNMENT_9000_SGL)) {
 						TW_PRINTK(tw_dev->host, TW_DRIVER, 0x2e, "Found unaligned sgl address during execute scsi");
 						goto out;
drivers/scsi/3w-xxxx.c +4 -4
index 656bdb1..3d005cf 100644
@@ -1767,7 +1767,7 @@ static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
 	u32 lba = 0x0, num_sectors = 0x0, buffaddr = 0x0;
 	int i, use_sg;
 	struct scsi_cmnd *srb;
-	struct scatterlist *sglist;
+	struct scatterlist *sglist, *sg;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n");
 
@@ -1837,9 +1837,9 @@ static int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
 		if (use_sg == 0)
 			return 1;
 
-		for (i=0;i<use_sg; i++) {
-			command_packet->byte8.io.sgl[i].address = sg_dma_address(&sglist[i]);
-			command_packet->byte8.io.sgl[i].length = sg_dma_len(&sglist[i]);
+		for_each_sg(sglist, sg, use_sg, i) {
+			command_packet->byte8.io.sgl[i].address = sg_dma_address(sg);
+			command_packet->byte8.io.sgl[i].length = sg_dma_len(sg);
 			command_packet->size+=2;
 		}
 	}
drivers/scsi/53c700.c +7 -9
index cb02656..821163d 100644
@@ -1887,6 +1887,7 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
 		int i;
 		int sg_count;
 		dma_addr_t vPtr = 0;
+		struct scatterlist *sgl, *sg;
 		__u32 count = 0;
 
 		if(SCp->use_sg) {
@@ -1902,15 +1903,12 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
 			slot->dma_handle = vPtr;
 			sg_count = 1;
 		}
-			
-
-		for(i = 0; i < sg_count; i++) {
-
-			if(SCp->use_sg) {
-				struct scatterlist *sg = SCp->request_buffer;
-
-				vPtr = sg_dma_address(&sg[i]);
-				count = sg_dma_len(&sg[i]);
+	
+		sgl = SCp->request_buffer;
+		for_each_sg(sgl, sg, sg_count, i) {
+			if (SCp->use_sg) {
+				vPtr = sg_dma_address(sg);
+				count = sg_dma_len(sg);
 			}
 
 			slot->SG[i].ins = bS_to_host(move_ins | count);
drivers/scsi/BusLogic.c +4 -3
index 96f4cab..7fd1cca 100644
@@ -2862,6 +2862,7 @@ static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRou
 				Command->sc_data_direction);
 	} else if (SegmentCount != 0) {
 		struct scatterlist *ScatterList = (struct scatterlist *) BufferPointer;
+		struct scatterlist *sg;
 		int Segment, Count;
 
 		Count = pci_map_sg(HostAdapter->PCI_Device, ScatterList, SegmentCount,
@@ -2872,9 +2873,9 @@ static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRou
 			CCB->DataPointer = (unsigned int) CCB->DMA_Handle + ((unsigned long) &CCB->ScatterGatherList - (unsigned long) CCB);
 		else
 			CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
-		for (Segment = 0; Segment < Count; Segment++) {
-			CCB->ScatterGatherList[Segment].SegmentByteCount = sg_dma_len(ScatterList + Segment);
-			CCB->ScatterGatherList[Segment].SegmentDataPointer = sg_dma_address(ScatterList + Segment);
+		for_each_sg(ScatterList, sg, Count, Segment) {
+			CCB->ScatterGatherList[Segment].SegmentByteCount = sg_dma_len(sg);
+			CCB->ScatterGatherList[Segment].SegmentDataPointer = sg_dma_address(sg);
 		}
 	} else {
 		CCB->Opcode = BusLogic_InitiatorCCB;
drivers/scsi/NCR53c406a.c +10 -8
index 7c0b17f..9402dd9 100644
@@ -875,12 +875,13 @@ static void NCR53c406a_intr(void *dev_id)
 			if (!current_SC->use_sg)	/* Don't use scatter-gather */
 				NCR53c406a_pio_write(current_SC->request_buffer, current_SC->request_bufflen);
 			else {	/* use scatter-gather */
+				struct scatterlist *sg;
+				int i;
+				
 				sgcount = current_SC->use_sg;
 				sglist = current_SC->request_buffer;
-				while (sgcount--) {
-					NCR53c406a_pio_write(page_address(sglist->page) + sglist->offset, sglist->length);
-					sglist++;
-				}
+				for_each_sg(sglist, sg, sgcount, i)
+					NCR53c406a_pio_write(page_address(sg->page) + sg->offset, sg->length);
 			}
 			REG0;
 #endif				/* USE_PIO */
@@ -902,12 +903,13 @@ static void NCR53c406a_intr(void *dev_id)
 			if (!current_SC->use_sg)	/* Don't use scatter-gather */
 				NCR53c406a_pio_read(current_SC->request_buffer, current_SC->request_bufflen);
 			else {	/* Use scatter-gather */
+				struct scatterlist *sg;
+				int i;
+
 				sgcount = current_SC->use_sg;
 				sglist = current_SC->request_buffer;
-				while (sgcount--) {
-					NCR53c406a_pio_read(page_address(sglist->page) + sglist->offset, sglist->length);
-					sglist++;
-				}
+				for_each_sg(sglist, sg, sgcount, i)
+					NCR53c406a_pio_read(page_address(sg->page) + sg->offset, sg->length);
 			}
 			REG0;
 #endif				/* USE_PIO */
drivers/scsi/a100u2w.c +5 -4
index 7f4241b..1353900 100644
@@ -796,7 +796,7 @@ static void orc_interrupt(
 *****************************************************************************/
 static void inia100BuildSCB(ORC_HCS * pHCB, ORC_SCB * pSCB, struct scsi_cmnd * SCpnt)
 {				/* Create corresponding SCB     */
-	struct scatterlist *pSrbSG;
+	struct scatterlist *pSrbSG, *sg;
 	ORC_SG *pSG;		/* Pointer to SG list           */
 	int i, count_sg;
 	ESCB *pEScb;
@@ -820,9 +820,10 @@ static void inia100BuildSCB(ORC_HCS * pHCB, ORC_SCB * pSCB, struct scsi_cmnd * S
 			count_sg = pci_map_sg(pHCB->pdev, pSrbSG, SCpnt->use_sg,
 					SCpnt->sc_data_direction);
 			pSCB->SCB_SGLen = (U32) (count_sg * 8);
-			for (i = 0; i < count_sg; i++, pSG++, pSrbSG++) {
-				pSG->SG_Ptr = (U32) sg_dma_address(pSrbSG);
-				pSG->SG_Len = (U32) sg_dma_len(pSrbSG);
+			for_each_sg(pSrbSG, sg, count_sg, i) {
+				pSG->SG_Ptr = (U32) sg_dma_address(sg);
+				pSG->SG_Len = (U32) sg_dma_len(sg);
+				pSG++;
 			}
 		} else if (SCpnt->request_bufflen != 0) {/* Non SG */
 			pSCB->SCB_SGLen = 0x8;
drivers/scsi/aacraid/aachba.c +13 -16
index 1e82c69..7fcac4e 100644
@@ -2347,7 +2347,7 @@ static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* psg)
 	psg->sg[0].addr = 0;
 	psg->sg[0].count = 0;  
 	if (scsicmd->use_sg) {
-		struct scatterlist *sg;
+		struct scatterlist *sg, *s;
 		int i;
 		int sg_count;
 		sg = (struct scatterlist *) scsicmd->request_buffer;
@@ -2356,11 +2356,10 @@ static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* psg)
 			scsicmd->sc_data_direction);
 		psg->count = cpu_to_le32(sg_count);
 
-		for (i = 0; i < sg_count; i++) {
-			psg->sg[i].addr = cpu_to_le32(sg_dma_address(sg));
-			psg->sg[i].count = cpu_to_le32(sg_dma_len(sg));
-			byte_count += sg_dma_len(sg);
-			sg++;
+		for_each_sg(sg, s, sg_count, i) {
+			psg->sg[i].addr = cpu_to_le32(sg_dma_address(s));
+			psg->sg[i].count = cpu_to_le32(sg_dma_len(s));
+			byte_count += sg_dma_len(s);
 		}
 		/* hba wants the size to be exact */
 		if(byte_count > scsicmd->request_bufflen){
@@ -2404,7 +2403,7 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
 	psg->sg[0].addr[1] = 0;
 	psg->sg[0].count = 0;
 	if (scsicmd->use_sg) {
-		struct scatterlist *sg;
+		struct scatterlist *sg, *s;
 		int i;
 		int sg_count;
 		sg = (struct scatterlist *) scsicmd->request_buffer;
@@ -2412,14 +2411,13 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
 		sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,
 			scsicmd->sc_data_direction);
 
-		for (i = 0; i < sg_count; i++) {
-			int count = sg_dma_len(sg);
-			addr = sg_dma_address(sg);
+		for_each_sg(sg, s, sg_count, i) {
+			int count = sg_dma_len(s);
+			addr = sg_dma_address(s);
 			psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff);
 			psg->sg[i].addr[1] = cpu_to_le32(addr>>32);
 			psg->sg[i].count = cpu_to_le32(count);
 			byte_count += count;
-			sg++;
 		}
 		psg->count = cpu_to_le32(sg_count);
 		/* hba wants the size to be exact */
@@ -2465,7 +2463,7 @@ static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw*
 	psg->sg[0].count = 0;
 	psg->sg[0].flags = 0;
 	if (scsicmd->use_sg) {
-		struct scatterlist *sg;
+		struct scatterlist *sg, *s;
 		int i;
 		int sg_count;
 		sg = (struct scatterlist *) scsicmd->request_buffer;
@@ -2473,9 +2471,9 @@ static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw*
 		sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,
 			scsicmd->sc_data_direction);
 
-		for (i = 0; i < sg_count; i++) {
-			int count = sg_dma_len(sg);
-			u64 addr = sg_dma_address(sg);
+		for_each_sg(sg, s, sg_count, i) {
+			int count = sg_dma_len(s);
+			u64 addr = sg_dma_address(s);
 			psg->sg[i].next = 0;
 			psg->sg[i].prev = 0;
 			psg->sg[i].addr[1] = cpu_to_le32((u32)(addr>>32));
@@ -2483,7 +2481,6 @@ static unsigned long aac_build_sgraw(struct scsi_cmnd* scsicmd, struct sgmapraw*
 			psg->sg[i].count = cpu_to_le32(count);
 			psg->sg[i].flags = 0;
 			byte_count += count;
-			sg++;
 		}
 		psg->count = cpu_to_le32(sg_count);
 		/* hba wants the size to be exact */
drivers/scsi/advansys.c +10 -11
index 9b3303b..06bf40c 100644
@@ -6468,7 +6468,7 @@ asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
          */
         int                     sgcnt;
 	int			use_sg;
-        struct scatterlist      *slp;
+        struct scatterlist      *slp, *sg;
 
 	slp = (struct scatterlist *)scp->request_buffer;
 	use_sg = dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction);
@@ -6502,10 +6502,10 @@ asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
         /*
          * Convert scatter-gather list into ASC_SG_HEAD list.
          */
-	for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) {
-	    asc_sg_head.sg_list[sgcnt].addr = cpu_to_le32(sg_dma_address(slp));
-	    asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(sg_dma_len(slp));
-	    ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
+	for_each_sg(slp, sg, use_sg, sgcnt) {
+	    asc_sg_head.sg_list[sgcnt].addr = cpu_to_le32(sg_dma_address(sg));
+	    asc_sg_head.sg_list[sgcnt].bytes = cpu_to_le32(sg_dma_len(sg));
+	    ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(sg), 512));
         }
     }
 
@@ -6700,7 +6700,7 @@ adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, int
 {
     adv_sgblk_t         *sgblkp;
     ADV_SCSI_REQ_Q      *scsiqp;
-    struct scatterlist  *slp;
+    struct scatterlist  *slp, *sg;
     int                 sg_elem_cnt;
     ADV_SG_BLOCK        *sg_block, *prev_sg_block;
     ADV_PADDR           sg_block_paddr;
@@ -6778,11 +6778,11 @@ adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, int
             }
         }
 
-        for (i = 0; i < NO_OF_SG_PER_BLOCK; i++)
+	for_each_sg(slp, sg, NO_OF_SG_PER_BLOCK, i)
         {
-	    sg_block->sg_list[i].sg_addr = cpu_to_le32(sg_dma_address(slp));
-	    sg_block->sg_list[i].sg_count = cpu_to_le32(sg_dma_len(slp));
-	    ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(slp), 512));
+	    sg_block->sg_list[i].sg_addr = cpu_to_le32(sg_dma_address(sg));
+	    sg_block->sg_list[i].sg_count = cpu_to_le32(sg_dma_len(sg));
+	    ASC_STATS_ADD(scp->device->host, sg_xfer, ASC_CEILING(sg_dma_len(sg), 512));
 
             if (--sg_elem_cnt == 0)
             {   /* Last ADV_SG_BLOCK and scatter-gather entry. */
@@ -6790,7 +6790,6 @@ adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, int
                 sg_block->sg_ptr = 0L;    /* Last ADV_SG_BLOCK in list. */
                 return ADV_SUCCESS;
             }
-            slp++;
         }
         sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
         prev_sg_block = sg_block;
drivers/scsi/aha1542.c +10 -11
index cbbfbc9..0a4d34b 100644
@@ -691,7 +691,7 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 	memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);
 
 	if (SCpnt->use_sg) {
-		struct scatterlist *sgpnt;
+		struct scatterlist *sgpnt, *sg;
 		struct chain *cptr;
 #ifdef DEBUG
 		unsigned char *ptr;
@@ -706,16 +706,15 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 			HOSTDATA(SCpnt->device->host)->SCint[mbo] = NULL;
 			return SCSI_MLQUEUE_HOST_BUSY;
 		}
-		for (i = 0; i < SCpnt->use_sg; i++) {
-			if (sgpnt[i].length == 0 || SCpnt->use_sg > 16 ||
-			    (((int) sgpnt[i].offset) & 1) || (sgpnt[i].length & 1)) {
+		for_each_sg(sgpnt, sg, SCpnt->use_sg, i) {
+			if (sg->length == 0 || SCpnt->use_sg > 16 ||
+			    (((int) sg->offset) & 1) || (sg->length & 1)) {
 				unsigned char *ptr;
 				printk(KERN_CRIT "Bad segment list supplied to aha1542.c (%d, %d)\n", SCpnt->use_sg, i);
-				for (i = 0; i < SCpnt->use_sg; i++) {
+				for_each_sg(sgpnt, sg, SCpnt->use_sg, i) {
 					printk(KERN_CRIT "%d: %p %d\n", i,
-					       (page_address(sgpnt[i].page) +
-						sgpnt[i].offset),
-					       sgpnt[i].length);
+					       (page_address(sg->page) +
+						sg->offset), sg->length);
 				};
 				printk(KERN_CRIT "cptr %x: ", (unsigned int) cptr);
 				ptr = (unsigned char *) &cptr[i];
@@ -723,10 +722,10 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 					printk("%02x ", ptr[i]);
 				panic("Foooooooood fight!");
 			};
-			any2scsi(cptr[i].dataptr, SCSI_SG_PA(&sgpnt[i]));
-			if (SCSI_SG_PA(&sgpnt[i]) + sgpnt[i].length - 1 > ISA_DMA_THRESHOLD)
+			any2scsi(cptr[i].dataptr, SCSI_SG_PA(sg));
+			if (SCSI_SG_PA(sg) + sg->length - 1 > ISA_DMA_THRESHOLD)
 				BAD_SG_DMA(SCpnt, sgpnt, SCpnt->use_sg, i);
-			any2scsi(cptr[i].datalen, sgpnt[i].length);
+			any2scsi(cptr[i].datalen, sg->length);
 		};
 		any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain));
 		any2scsi(ccb[mbo].dataptr, SCSI_BUF_PA(cptr));
drivers/scsi/aha1740.c +4 -4
index d7af9c6..2641c24 100644
@@ -425,7 +425,7 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
 	sgptr->sg_dma_addr = sg_dma;
     
 	if (SCpnt->use_sg) {
-		struct scatterlist * sgpnt;
+		struct scatterlist * sgpnt, * sg;
 		struct aha1740_chain * cptr;
 		int i, count;
 		DEB(unsigned char * ptr);
@@ -436,9 +436,9 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
 		cptr = sgptr->sg_chain;
 		count = dma_map_sg (&host->edev->dev, sgpnt, SCpnt->use_sg,
 				    SCpnt->sc_data_direction);
-		for(i=0; i < count; i++) {
-			cptr[i].datalen = sg_dma_len (sgpnt + i);
-			cptr[i].dataptr = sg_dma_address (sgpnt + i);
+		for_each_sg(sgpnt, sg, count, i) {
+			cptr[i].datalen = sg_dma_len (sg);
+			cptr[i].dataptr = sg_dma_address (sg);
 		}
 		host->ecb[ecbno].datalen = count*sizeof(struct aha1740_chain);
 		host->ecb[ecbno].dataptr = sg_dma;
drivers/scsi/aic7xxx/aic79xx_osm.c +2 -1
index 6054881..e7ab15b 100644
@@ -1505,7 +1505,7 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
 		nseg = pci_map_sg(ahd->dev_softc, cur_seg,
 				  cmd->use_sg, dir);
 		scb->platform_data->xfer_len = 0;
-		for (sg = scb->sg_list; nseg > 0; nseg--, cur_seg++) {
+		for (sg = scb->sg_list; nseg > 0; nseg--) {
 			dma_addr_t addr;
 			bus_size_t len;
 
@@ -1514,6 +1514,7 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
 			scb->platform_data->xfer_len += len;
 			sg = ahd_sg_setup(ahd, scb, sg, addr, len,
 					  /*last*/nseg == 1);
+			cur_seg = sg_next(cur_seg);
 		}
 	} else if (cmd->request_bufflen != 0) {
 		void *sg;
drivers/scsi/aic7xxx/aic7xxx_osm.c +5 -7
index 660f26e..bf85297 100644
@@ -1475,20 +1475,19 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
 	if (cmd->use_sg != 0) {
 		struct	ahc_dma_seg *sg;
 		struct	scatterlist *cur_seg;
-		struct	scatterlist *end_seg;
-		int	nseg;
+		struct	scatterlist *sgl;
+		int	nseg, i;
 
-		cur_seg = (struct scatterlist *)cmd->request_buffer;
-		nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg,
+		sgl = (struct scatterlist *)cmd->request_buffer;
+		nseg = pci_map_sg(ahc->dev_softc, sgl, cmd->use_sg,
 				  cmd->sc_data_direction);
-		end_seg = cur_seg + nseg;
 		/* Copy the segments into the SG list. */
 		sg = scb->sg_list;
 		/*
 		 * The sg_count may be larger than nseg if
 		 * a transfer crosses a 32bit page.
 		 */ 
-		while (cur_seg < end_seg) {
+		for_each_sg(sgl, cur_seg, nseg, i) {
 			dma_addr_t addr;
 			bus_size_t len;
 			int consumed;
@@ -1499,7 +1498,6 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
 						     sg, addr, len);
 			sg += consumed;
 			scb->sg_count += consumed;
-			cur_seg++;
 		}
 		sg--;
 		sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
drivers/scsi/aic94xx/aic94xx_task.c +3 -3
index e2ad5be..1327281 100644
@@ -89,7 +89,7 @@ static inline int asd_map_scatterlist(struct sas_task *task,
 			res = -ENOMEM;
 			goto err_unmap;
 		}
-		for (sc = task->scatter, i = 0; i < num_sg; i++, sc++) {
+		for_each_sg(task->scatter, sc, num_sg, i) {
 			struct sg_el *sg =
 				&((struct sg_el *)ascb->sg_arr->vaddr)[i];
 			sg->bus_addr = cpu_to_le64((u64)sg_dma_address(sc));
@@ -98,7 +98,7 @@ static inline int asd_map_scatterlist(struct sas_task *task,
 				sg->flags |= ASD_SG_EL_LIST_EOL;
 		}
 
-		for (sc = task->scatter, i = 0; i < 2; i++, sc++) {
+		for_each_sg(task->scatter, sc, 2, i) {
 			sg_arr[i].bus_addr =
 				cpu_to_le64((u64)sg_dma_address(sc));
 			sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc));
@@ -110,7 +110,7 @@ static inline int asd_map_scatterlist(struct sas_task *task,
 		sg_arr[2].bus_addr=cpu_to_le64((u64)ascb->sg_arr->dma_handle);
 	} else {
 		int i;
-		for (sc = task->scatter, i = 0; i < num_sg; i++, sc++) {
+		for_each_sg(task->scatter, sc, num_sg, i) {
 			sg_arr[i].bus_addr =
 				cpu_to_le64((u64)sg_dma_address(sc));
 			sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc));
drivers/scsi/arcmsr/arcmsr_hba.c +5 -6
index 8b46158..c2e2e95 100644
@@ -563,18 +563,18 @@ static void arcmsr_build_ccb(struct AdapterControlBlock *acb,
 	memcpy(arcmsr_cdb->Cdb, pcmd->cmnd, pcmd->cmd_len);
 	if (pcmd->use_sg) {
 		int length, sgcount, i, cdb_sgcount = 0;
-		struct scatterlist *sl;
+		struct scatterlist *sl, *sg;
 
 		/* Get Scatter Gather List from scsiport. */
 		sl = (struct scatterlist *) pcmd->request_buffer;
 		sgcount = pci_map_sg(acb->pdev, sl, pcmd->use_sg,
 				pcmd->sc_data_direction);
 		/* map stor port SG list to our iop SG List. */
-		for (i = 0; i < sgcount; i++) {
+		for_each_sg(sl, sg, sgcount, i) {
 			/* Get the physical address of the current data pointer */
-			length = cpu_to_le32(sg_dma_len(sl));
-			address_lo = cpu_to_le32(dma_addr_lo32(sg_dma_address(sl)));
-			address_hi = cpu_to_le32(dma_addr_hi32(sg_dma_address(sl)));
+			length = cpu_to_le32(sg_dma_len(sg));
+			address_lo = cpu_to_le32(dma_addr_lo32(sg_dma_address(sg)));
+			address_hi = cpu_to_le32(dma_addr_hi32(sg_dma_address(sg)));
 			if (address_hi == 0) {
 				struct SG32ENTRY *pdma_sg = (struct SG32ENTRY *)psge;
 
@@ -591,7 +591,6 @@ static void arcmsr_build_ccb(struct AdapterControlBlock *acb,
 				psge += sizeof (struct SG64ENTRY);
 				arccdbsize += sizeof (struct SG64ENTRY);
 			}
-			sl++;
 			cdb_sgcount++;
 		}
 		arcmsr_cdb->sgcount = (uint8_t)cdb_sgcount;
drivers/scsi/dc395x.c +4 -3
index 564ea90..4e0f073 100644
@@ -1010,6 +1010,7 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
 		u32 reqlen = cmd->request_bufflen;
 		struct scatterlist *sl = (struct scatterlist *)
 					 cmd->request_buffer;
+		struct scatterlist *sg;
 		struct SGentry *sgp = srb->segment_x;
 		srb->sg_count = pci_map_sg(dcb->acb->dev, sl, cmd->use_sg,
 					   dir);
@@ -1018,9 +1019,9 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
 			reqlen, cmd->request_buffer, cmd->use_sg,
 			srb->sg_count);
 
-		for (i = 0; i < srb->sg_count; i++) {
-			u32 busaddr = (u32)sg_dma_address(&sl[i]);
-			u32 seglen = (u32)sl[i].length;
+		for_each_sg(sl, sg, srb->sg_count, i) {
+			u32 busaddr = (u32)sg_dma_address(sg);
+			u32 seglen = (u32)sg->length;
 			sgp[i].address = busaddr;
 			sgp[i].length = seglen;
 			srb->total_xfer_length += seglen;
drivers/scsi/dpt_i2o.c +7 -6
index 8c7d2bb..b63d4b2 100644
@@ -2141,20 +2141,21 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d
 	reqlen = 14;		// SINGLE SGE
 	/* Now fill in the SGList and command */
 	if(cmd->use_sg) {
-		struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer;
-		int sg_count = pci_map_sg(pHba->pDev, sg, cmd->use_sg,
+		struct scatterlist *sgl = (struct scatterlist *)cmd->request_buffer;
+		struct scatterlist *sg;
+		int sg_count = pci_map_sg(pHba->pDev, sgl, cmd->use_sg,
 				cmd->sc_data_direction);
 
 
 		len = 0;
-		for(i = 0 ; i < sg_count; i++) {
+		for_each_sg(sgl, sg, sg_count, i) {
 			*mptr++ = direction|0x10000000|sg_dma_len(sg);
 			len+=sg_dma_len(sg);
 			*mptr++ = sg_dma_address(sg);
-			sg++;
+			/* Make this an end of list */
+			if (i == sg_count - 1)
+				mptr[-2] = direction|0xD0000000|sg_dma_len(sg);
 		}
-		/* Make this an end of list */
-		mptr[-2] = direction|0xD0000000|sg_dma_len(sg-1);
 		reqlen = mptr - msg;
 		*lenptr = len;
 		
drivers/scsi/eata.c +4 -4
index 2d38025..9526fa9 100644
@@ -1610,7 +1610,7 @@ static int eata2x_detect(struct scsi_host_template *tpnt)
 static void map_dma(unsigned int i, struct hostdata *ha)
 {
 	unsigned int k, count, pci_dir;
-	struct scatterlist *sgpnt;
+	struct scatterlist *sgpnt, *sg;
 	struct mscp *cpp;
 	struct scsi_cmnd *SCpnt;
 
@@ -1646,9 +1646,9 @@ static void map_dma(unsigned int i, struct hostdata *ha)
 	sgpnt = (struct scatterlist *)SCpnt->request_buffer;
 	count = pci_map_sg(ha->pdev, sgpnt, SCpnt->use_sg, pci_dir);
 
-	for (k = 0; k < count; k++) {
-		cpp->sglist[k].address = H2DEV(sg_dma_address(&sgpnt[k]));
-		cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(&sgpnt[k]));
+	for_each_sg(sgpnt, sg, count, k) {
+		cpp->sglist[k].address = H2DEV(sg_dma_address(sg));
+		cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(sg));
 	}
 
 	cpp->sg = 1;
drivers/scsi/esp_scsi.c +3 -2
index ec71061..4c29d29 100644
@@ -325,6 +325,7 @@ static void esp_map_dma(struct esp *esp, struct scsi_cmnd *cmd)
 {
 	struct esp_cmd_priv *spriv = ESP_CMD_PRIV(cmd);
 	struct scatterlist *sg = cmd->request_buffer;
+	struct scatterlist *s;
 	int dir = cmd->sc_data_direction;
 	int total, i;
 
@@ -339,8 +340,8 @@ static void esp_map_dma(struct esp *esp, struct scsi_cmnd *cmd)
 	spriv->cur_sg = sg;
 
 	total = 0;
-	for (i = 0; i < spriv->u.num_sg; i++)
-		total += sg_dma_len(&sg[i]);
+	for_each_sg(sg, s, spriv->u.num_sg, i)
+		total += sg_dma_len(s);
 	spriv->tot_residue = total;
 }
 
drivers/scsi/gdth.c +23 -22

123 lines not on this page · raw message

drivers/scsi/hptiop.c +4 -4
index bec83cb..5b1c210 100644
@@ -449,6 +449,7 @@ static int hptiop_buildsgl(struct scsi_cmnd *scp, struct hpt_iopsg *psg)
 	struct Scsi_Host *host = scp->device->host;
 	struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata;
 	struct scatterlist *sglist = (struct scatterlist *)scp->request_buffer;
+	struct scatterlist *sg;
 
 	/*
 	 * though we'll not get non-use_sg fields anymore,
@@ -463,10 +464,9 @@ static int hptiop_buildsgl(struct scsi_cmnd *scp, struct hpt_iopsg *psg)
 		HPT_SCP(scp)->mapped = 1;
 		BUG_ON(HPT_SCP(scp)->sgcnt > hba->max_sg_descriptors);
 
-		for (idx = 0; idx < HPT_SCP(scp)->sgcnt; idx++) {
-			psg[idx].pci_address =
-				cpu_to_le64(sg_dma_address(&sglist[idx]));
-			psg[idx].size = cpu_to_le32(sg_dma_len(&sglist[idx]));
+		for_each_sg(sglist, sg, HPT_SCP(scp)->sgcnt, idx) {
+			psg[idx].pci_address = cpu_to_le64(sg_dma_address(sg));
+			psg[idx].size = cpu_to_le32(sg_dma_len(sg));
 			psg[idx].eot = (idx == HPT_SCP(scp)->sgcnt - 1) ?
 				cpu_to_le32(1) : 0;
 		}
drivers/scsi/ibmmca.c +5 -6
index 0e57fb6..f6c2581 100644
@@ -1808,7 +1808,7 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 	int host_index;
 	int max_pun;
 	int i;
-	struct scatterlist *sl;
+	struct scatterlist *sl, *sg;
 
 	shpnt = cmd->device->host;
 	/* search for the right hostadapter */
@@ -1938,13 +1938,12 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 	scsi_cmd = cmd->cmnd[0];
 
 	if (cmd->use_sg) {
-		i = cmd->use_sg;
 		sl = (struct scatterlist *) (cmd->request_buffer);
-		if (i > 16)
+		if (cmd->use_sg > 16)
 			panic("IBM MCA SCSI: scatter-gather list too long.\n");
-		while (--i >= 0) {
-			ld(host_index)[ldn].sge[i].address = (void *) (isa_page_to_bus(sl[i].page) + sl[i].offset);
-			ld(host_index)[ldn].sge[i].byte_length = sl[i].length;
+		for_each_sg(sl, sg, cmd->use_sg, i) {
+			ld(host_index)[ldn].sge[i].address = (void *) (isa_page_to_bus(sg->page) + sg->offset);
+			ld(host_index)[ldn].sge[i].byte_length = sg->length;
 		}
 		scb->enable |= IM_POINTER_TO_LIST;
 		scb->sys_buf_adr = isa_virt_to_bus(&(ld(host_index)[ldn].sge[0]));
drivers/scsi/ibmvscsi/ibmvscsi.c +2 -2
index b10eefe..943a01e 100644
@@ -359,10 +359,10 @@ static int map_sg_list(int num_entries,
 {
 	int i;
 	u64 total_length = 0;
+	struct scatterlist *sg_entry;
 
-	for (i = 0; i < num_entries; ++i) {
+	for_each_sg(sg, sg_entry, num_entries, i) {
 		struct srp_direct_buf *descr = md + i;
-		struct scatterlist *sg_entry = &sg[i];
 		descr->va = sg_dma_address(sg_entry);
 		descr->len = sg_dma_len(sg_entry);
 		descr->key = 0;
drivers/scsi/ide-scsi.c +19 -12
index 8263f75..9101928 100644
@@ -70,6 +70,7 @@ typedef struct idescsi_pc_s {
 	u8 *buffer;				/* Data buffer */
 	u8 *current_position;			/* Pointer into the above buffer */
 	struct scatterlist *sg;			/* Scatter gather table */
+	struct scatterlist *last_sg;		/* Last sg element */
 	int b_count;				/* Bytes transferred from current entry */
 	struct scsi_cmnd *scsi_cmd;		/* SCSI command */
 	void (*done)(struct scsi_cmnd *);	/* Scsi completion routine */
@@ -175,11 +176,6 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
 	char *buf;
 
 	while (bcount) {
-		if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) {
-			printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n");
-			idescsi_discard_data (drive, bcount);
-			return;
-		}
 		count = min(pc->sg->length - pc->b_count, bcount);
 		if (PageHighMem(pc->sg->page)) {
 			unsigned long flags;
@@ -198,10 +194,17 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
 		}
 		bcount -= count; pc->b_count += count;
 		if (pc->b_count == pc->sg->length) {
-			pc->sg++;
+			if (pc->sg == pc->last_sg)
+				break;
+			pc->sg = sg_next(pc->sg);
 			pc->b_count = 0;
 		}
 	}
+
+	if (bcount) {
+		printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n");
+		idescsi_discard_data (drive, bcount);
+	}
 }
 
 static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount)
@@ -210,11 +213,6 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
 	char *buf;
 
 	while (bcount) {
-		if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) {
-			printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n");
-			idescsi_output_zeros (drive, bcount);
-			return;
-		}
 		count = min(pc->sg->length - pc->b_count, bcount);
 		if (PageHighMem(pc->sg->page)) {
 			unsigned long flags;
@@ -233,10 +231,17 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
 		}
 		bcount -= count; pc->b_count += count;
 		if (pc->b_count == pc->sg->length) {
-			pc->sg++;
+			if (pc->sg == pc->last_sg)
+				break;
+			pc->sg = sg_next(pc->sg);
 			pc->b_count = 0;
 		}
 	}
+
+	if (bcount) {
+		printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n");
+		idescsi_output_zeros (drive, bcount);
+	}
 }
 
 /*
@@ -910,9 +915,11 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
 	if (cmd->use_sg) {
 		pc->buffer = NULL;
 		pc->sg = cmd->request_buffer;
+		pc->last_sg = sg_last(pc->sg, cmd->use_sg);
 	} else {
 		pc->buffer = cmd->request_buffer;
 		pc->sg = NULL;
+		pc->last_sg = NULL;
 	}
 	pc->b_count = 0;
 	pc->request_transfer = pc->buffer_size = cmd->request_bufflen;
drivers/scsi/initio.c +7 -5
index 7e7635c..300d33d 100644
@@ -2882,7 +2882,7 @@ static int i91u_detect(struct scsi_host_template * tpnt)
 
 static void i91uBuildSCB(HCS * pHCB, SCB * pSCB, struct scsi_cmnd * SCpnt)
 {				/* Create corresponding SCB     */
-	struct scatterlist *pSrbSG;
+	struct scatterlist *pSrbSG, *sg;
 	SG *pSG;		/* Pointer to SG list           */
 	int i;
 	long TotalLen;
@@ -2926,10 +2926,12 @@ static void i91uBuildSCB(HCS * pHCB, SCB * pSCB, struct scsi_cmnd * SCpnt)
 					     SCpnt->use_sg, SCpnt->sc_data_direction);
 
 		pSCB->SCB_Flags |= SCF_SG;	/* Turn on SG list flag       */
-		for (i = 0, TotalLen = 0, pSG = &pSCB->SCB_SGList[0];	/* 1.01g */
-		     i < pSCB->SCB_SGLen; i++, pSG++, pSrbSG++) {
-			pSG->SG_Ptr = cpu_to_le32((u32)sg_dma_address(pSrbSG));
-			TotalLen += pSG->SG_Len = cpu_to_le32((u32)sg_dma_len(pSrbSG));
+		pSG = &pSCB->SCB_SGList[0];
+		TotalLen = 0;
+		for_each_sg(pSrbSG, sg, pSCB->SCB_SGLen, i) {
+			pSG->SG_Ptr = cpu_to_le32((u32)sg_dma_address(sg));
+			TotalLen += pSG->SG_Len = cpu_to_le32((u32)sg_dma_len(sg));
+			pSG++;
 		}
 
 		pSCB->SCB_BufLen = (SCpnt->request_bufflen > TotalLen) ?
drivers/scsi/ipr.c +4 -5
index 4baa79e..01b0476 100644
@@ -4286,7 +4286,7 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
 			   struct ipr_cmnd *ipr_cmd)
 {
 	int i;
-	struct scatterlist *sglist;
+	struct scatterlist *sglist, *sg;
 	u32 length;
 	u32 ioadl_flags = 0;
 	struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd;
@@ -4327,11 +4327,10 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg,
 			ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr;
 		}
 
-		for (i = 0; i < ipr_cmd->dma_use_sg; i++) {
+		for_each_sg(sglist, sg, ipr_cmd->dma_use_sg, i) {
 			ioadl[i].flags_and_data_len =
-				cpu_to_be32(ioadl_flags | sg_dma_len(&sglist[i]));
-			ioadl[i].address =
-				cpu_to_be32(sg_dma_address(&sglist[i]));
+				cpu_to_be32(ioadl_flags | sg_dma_len(sg));
+			ioadl[i].address = cpu_to_be32(sg_dma_address(sg));
 		}
 
 		if (likely(ipr_cmd->dma_use_sg)) {
drivers/scsi/ips.c +41 -33

134 lines not on this page · raw message

drivers/scsi/iscsi_tcp.c +22 -21

104 lines not on this page · raw message

drivers/scsi/jazz_esp.c +14 -13
index 19dd4b9..d742c73 100644
@@ -15,6 +15,7 @@
 #include <linux/blkdev.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
+#include <linux/dma-mapping.h>
 
 #include "scsi.h"
 #include <scsi/scsi_host.h>
@@ -240,12 +241,13 @@ static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
 static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp)
 {
     int sz = sp->SCp.buffers_residual;
-    struct scatterlist *sg = (struct scatterlist *) sp->SCp.buffer;
-    
-    while (sz >= 0) {
-	sg[sz].dma_address = vdma_alloc(CPHYSADDR(page_address(sg[sz].page) + sg[sz].offset), sg[sz].length);
-	sz--;
-    }
+    struct scatterlist *sgl = (struct scatterlist *) sp->SCp.buffer;
+    struct scatterlist *sg;
+    int i;
+
+    for_each_sg(sgl, sg, sz, i)
+	sg->dma_address = vdma_alloc(CPHYSADDR(page_address(sg->page) + sg->offset), sg->length);
+
     sp->SCp.ptr=(char *)(sp->SCp.buffer->dma_address);
 }    
 
@@ -256,13 +258,12 @@ static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
 
 static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp)
 {
-    int sz = sp->use_sg - 1;
-    struct scatterlist *sg = (struct scatterlist *)sp->request_buffer;
-			
-    while(sz >= 0) {
-	vdma_free(sg[sz].dma_address);
-	sz--;
-    }
+    struct scatterlist *sgl = (struct scatterlist *)sp->request_buffer;
+    struct scatterlist *sg;
+    int i;
+
+    for_each_sg(sgl, sg, sp->use_sg, i)
+	vdma_free(sg->dma_address);
 }
 
 static void dma_advance_sg (struct scsi_cmnd *sp)
drivers/scsi/lpfc/lpfc_scsi.c +4 -5
index 9a12d05..d1f6654 100644
@@ -169,7 +169,7 @@ static int
 lpfc_scsi_prep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd)
 {
 	struct scsi_cmnd *scsi_cmnd = lpfc_cmd->pCmd;
-	struct scatterlist *sgel = NULL;
+	struct scatterlist *sgel = NULL, *sg;
 	struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
 	struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl;
 	IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
@@ -214,18 +214,17 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd)
 		 * single scsi command.  Just run through the seg_cnt and format
 		 * the bde's.
 		 */
-		for (i = 0; i < lpfc_cmd->seg_cnt; i++) {
-			physaddr = sg_dma_address(sgel);
+		for_each_sg(sgel, sg, lpfc_cmd->seg_cnt, i) {
+			physaddr = sg_dma_address(sg);
 			bpl->addrLow = le32_to_cpu(putPaddrLow(physaddr));
 			bpl->addrHigh = le32_to_cpu(putPaddrHigh(physaddr));
-			bpl->tus.f.bdeSize = sg_dma_len(sgel);
+			bpl->tus.f.bdeSize = sg_dma_len(sg);
 			if (datadir == DMA_TO_DEVICE)
 				bpl->tus.f.bdeFlags = 0;
 			else
 				bpl->tus.f.bdeFlags = BUFF_USE_RCV;
 			bpl->tus.w = le32_to_cpu(bpl->tus.w);
 			bpl++;
-			sgel++;
 			num_bde++;
 		}
 	} else if (scsi_cmnd->request_buffer && scsi_cmnd->request_bufflen) {
drivers/scsi/mac53c94.c +4 -5
index 5806ede..cb569c6 100644
@@ -366,7 +366,7 @@ static void cmd_done(struct fsc_state *state, int result)
 static void set_dma_cmds(struct fsc_state *state, struct scsi_cmnd *cmd)
 {
 	int i, dma_cmd, total;
-	struct scatterlist *scl;
+	struct scatterlist *scl, *sg;
 	struct dbdma_cmd *dcmds;
 	dma_addr_t dma_addr;
 	u32 dma_len;
@@ -381,9 +381,9 @@ static void set_dma_cmds(struct fsc_state *state, struct scsi_cmnd *cmd)
 		scl = (struct scatterlist *) cmd->request_buffer;
 		nseg = pci_map_sg(state->pdev, scl, cmd->use_sg,
 				cmd->sc_data_direction);
-		for (i = 0; i < nseg; ++i) {
-			dma_addr = sg_dma_address(scl);
-			dma_len = sg_dma_len(scl);
+		for_each_sg(scl, sg, nseg, i) {
+			dma_addr = sg_dma_address(sg);
+			dma_len = sg_dma_len(sg);
 			if (dma_len > 0xffff)
 				panic("mac53c94: scatterlist element >= 64k");
 			total += dma_len;
@@ -391,7 +391,6 @@ static void set_dma_cmds(struct fsc_state *state, struct scsi_cmnd *cmd)
 			st_le16(&dcmds->command, dma_cmd);
 			st_le32(&dcmds->phy_addr, dma_addr);
 			dcmds->xfer_status = 0;
-			++scl;
 			++dcmds;
 		}
 	} else {
drivers/scsi/megaraid.c +6 -7
index 3cce75d..0ea9ef4 100644
@@ -1767,7 +1767,7 @@ __mega_busywait_mbox (adapter_t *adapter)
 static int
 mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
 {
-	struct scatterlist	*sgl;
+	struct scatterlist	*sgl, *sg;
 	struct page	*page;
 	unsigned long	offset;
 	unsigned int	length;
@@ -1832,15 +1832,14 @@ mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
 
 	*len = 0;
 
-	for( idx = 0; idx < sgcnt; idx++, sgl++ ) {
-
+	for_each_sg(sgl, sg, sgcnt, idx) {
 		if( adapter->has_64bit_addr ) {
-			scb->sgl64[idx].address = sg_dma_address(sgl);
-			*len += scb->sgl64[idx].length = sg_dma_len(sgl);
+			scb->sgl64[idx].address = sg_dma_address(sg);
+			*len += scb->sgl64[idx].length = sg_dma_len(sg);
 		}
 		else {
-			scb->sgl[idx].address = sg_dma_address(sgl);
-			*len += scb->sgl[idx].length = sg_dma_len(sgl);
+			scb->sgl[idx].address = sg_dma_address(sg);
+			*len += scb->sgl[idx].length = sg_dma_len(sg);
 		}
 	}
 
drivers/scsi/megaraid/megaraid_mbox.c +4 -3
index 04d0b69..6b1ee7f 100644
@@ -1377,6 +1377,7 @@ static int
 megaraid_mbox_mksgl(adapter_t *adapter, scb_t *scb)
 {
 	struct scatterlist	*sgl;
+	struct scatterlist	*sg;
 	mbox_ccb_t		*ccb;
 	struct page		*page;
 	unsigned long		offset;
@@ -1429,9 +1430,9 @@ megaraid_mbox_mksgl(adapter_t *adapter, scb_t *scb)
 
 	scb->dma_type = MRAID_DMA_WSG;
 
-	for (i = 0; i < sgcnt; i++, sgl++) {
-		ccb->sgl64[i].address	= sg_dma_address(sgl);
-		ccb->sgl64[i].length	= sg_dma_len(sgl);
+	for_each_sg(sgl, sg, sgcnt, i) {
+		ccb->sgl64[i].address	= sg_dma_address(sg);
+		ccb->sgl64[i].length	= sg_dma_len(sg);
 	}
 
 	// Return count of SG nodes
drivers/scsi/megaraid/megaraid_sas.c +8 -8
index 7a81267..5260bc6 100644
@@ -431,7 +431,7 @@ megasas_make_sgl32(struct megasas_instance *instance, struct scsi_cmnd *scp,
 {
 	int i;
 	int sge_count;
-	struct scatterlist *os_sgl;
+	struct scatterlist *os_sgl, *sg;
 
 	/*
 	 * Return 0 if there is no data transfer
@@ -456,9 +456,9 @@ megasas_make_sgl32(struct megasas_instance *instance, struct scsi_cmnd *scp,
 	sge_count = pci_map_sg(instance->pdev, os_sgl, scp->use_sg,
 			       scp->sc_data_direction);
 
-	for (i = 0; i < sge_count; i++, os_sgl++) {
-		mfi_sgl->sge32[i].length = sg_dma_len(os_sgl);
-		mfi_sgl->sge32[i].phys_addr = sg_dma_address(os_sgl);
+	for_each_sg(os_sgl, sg, sge_count, i) {
+		mfi_sgl->sge32[i].length = sg_dma_len(sg);
+		mfi_sgl->sge32[i].phys_addr = sg_dma_address(sg);
 	}
 
 	return sge_count;
@@ -479,7 +479,7 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
 {
 	int i;
 	int sge_count;
-	struct scatterlist *os_sgl;
+	struct scatterlist *os_sgl, *sg;
 
 	/*
 	 * Return 0 if there is no data transfer
@@ -505,9 +505,9 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
 	sge_count = pci_map_sg(instance->pdev, os_sgl, scp->use_sg,
 			       scp->sc_data_direction);
 
-	for (i = 0; i < sge_count; i++, os_sgl++) {
-		mfi_sgl->sge64[i].length = sg_dma_len(os_sgl);
-		mfi_sgl->sge64[i].phys_addr = sg_dma_address(os_sgl);
+	for_each_sg(os_sgl, sg, sge_count, i) {
+		mfi_sgl->sge64[i].length = sg_dma_len(sg);
+		mfi_sgl->sge64[i].phys_addr = sg_dma_address(sg);
 	}
 
 	return sge_count;
drivers/scsi/mesh.c +6 -6
index e64d1a1..66519aa 100644
@@ -1257,7 +1257,7 @@ static void handle_msgin(struct mesh_state *ms)
 static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd)
 {
 	int i, dma_cmd, total, off, dtot;
-	struct scatterlist *scl;
+	struct scatterlist *scl, *sg;
 	struct dbdma_cmd *dcmds;
 
 	dma_cmd = ms->tgts[ms->conn_tgt].data_goes_out?
@@ -1267,17 +1267,17 @@ static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd)
 	if (cmd) {
 		cmd->SCp.this_residual = cmd->request_bufflen;
 		if (cmd->use_sg > 0) {
-			int nseg;
+			int nseg, i;
 			total = 0;
 			scl = (struct scatterlist *) cmd->request_buffer;
 			off = ms->data_ptr;
 			nseg = pci_map_sg(ms->pdev, scl, cmd->use_sg,
 					  cmd->sc_data_direction);
-			for (i = 0; i <nseg; ++i, ++scl) {
-				u32 dma_addr = sg_dma_address(scl);
-				u32 dma_len = sg_dma_len(scl);
+			for_each_sg(scl, sg, nseg, i) {
+				u32 dma_addr = sg_dma_address(sg);
+				u32 dma_len = sg_dma_len(sg);
 				
-				total += scl->length;
+				total += sg->length;
 				if (off >= dma_len) {
 					off -= dma_len;
 					continue;
drivers/scsi/ncr53c8xx.c +4 -3
index bbf521c..e6210c6 100644
@@ -7700,6 +7700,7 @@ static int ncr_scatter(struct ncb *np, struct ccb *cp, struct scsi_cmnd *cmd)
 		segment = ncr_scatter_no_sglist(np, cp, cmd);
 	else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) {
 		struct scatterlist *scatter = (struct scatterlist *)cmd->request_buffer;
+		struct scatterlist *sg;
 		struct scr_tblmove *data;
 
 		if (use_sg > MAX_SCATTER) {
@@ -7709,9 +7710,9 @@ static int ncr_scatter(struct ncb *np, struct ccb *cp, struct scsi_cmnd *cmd)
 
 		data = &cp->phys.data[MAX_SCATTER - use_sg];
 
-		for (segment = 0; segment < use_sg; segment++) {
-			dma_addr_t baddr = sg_dma_address(&scatter[segment]);
-			unsigned int len = sg_dma_len(&scatter[segment]);
+		for_each_sg(scatter, sg, use_sg, segment) {
+			dma_addr_t baddr = sg_dma_address(sg);
+			unsigned int len = sg_dma_len(sg);
 
 			ncr_build_sge(np, &data[segment], baddr, len);
 			cp->data_len += len;
drivers/scsi/nsp32.c +4 -5
index f6f561d..32426a9 100644
@@ -888,7 +888,7 @@ static int nsp32_reselection(struct scsi_cmnd *SCpnt, unsigned char newlun)
 static int nsp32_setup_sg_table(struct scsi_cmnd *SCpnt)
 {
 	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
-	struct scatterlist   *sgl;
+	struct scatterlist   *sgl, *sg;
 	nsp32_sgtable *sgt = data->cur_lunt->sglun->sgt;
 	int num, i;
 	u32_le l;
@@ -906,13 +906,12 @@ static int nsp32_setup_sg_table(struct scsi_cmnd *SCpnt)
 		sgl = (struct scatterlist *)SCpnt->request_buffer;
 		num = pci_map_sg(data->Pci, sgl, SCpnt->use_sg,
 				 SCpnt->sc_data_direction);
-		for (i = 0; i < num; i++) {
+		for_each_sg(sgl, sg, num, i) {
 			/*
 			 * Build nsp32_sglist, substitute sg dma addresses.
 			 */
-			sgt[i].addr = cpu_to_le32(sg_dma_address(sgl));
-			sgt[i].len  = cpu_to_le32(sg_dma_len(sgl));
-			sgl++;
+			sgt[i].addr = cpu_to_le32(sg_dma_address(sg));
+			sgt[i].len  = cpu_to_le32(sg_dma_len(sg));
 
 			if (le32_to_cpu(sgt[i].len) > 0x10000) {
 				nsp32_msg(KERN_ERR,
drivers/scsi/pcmcia/sym53c500_cs.c +10 -8
index ffe75c4..b1e9270 100644
@@ -442,12 +442,13 @@ SYM53C500_intr(int irq, void *dev_id)
 			if (!curSC->use_sg)	/* Don't use scatter-gather */
 				SYM53C500_pio_write(fast_pio, port_base, curSC->request_buffer, curSC->request_bufflen);
 			else {	/* use scatter-gather */
+				struct scatterlist *sg;
+				int i;
+
 				sgcount = curSC->use_sg;
 				sglist = curSC->request_buffer;
-				while (sgcount--) {
-					SYM53C500_pio_write(fast_pio, port_base, page_address(sglist->page) + sglist->offset, sglist->length);
-					sglist++;
-				}
+				for_each_sg(sglist, sg, sgcount, i)
+					SYM53C500_pio_write(fast_pio, port_base, page_address(sg->page) + sg->offset, sg->length);
 			}
 			REG0(port_base);
 		}
@@ -463,12 +464,13 @@ SYM53C500_intr(int irq, void *dev_id)
 			if (!curSC->use_sg)	/* Don't use scatter-gather */
 				SYM53C500_pio_read(fast_pio, port_base, curSC->request_buffer, curSC->request_bufflen);
 			else {	/* Use scatter-gather */
+				struct scatterlist *sg;
+				int i;
+
 				sgcount = curSC->use_sg;
 				sglist = curSC->request_buffer;
-				while (sgcount--) {
-					SYM53C500_pio_read(fast_pio, port_base, page_address(sglist->page) + sglist->offset, sglist->length);
-					sglist++;
-				}
+				for_each_sg(sglist, sg, sgcount, i)
+					SYM53C500_pio_read(fast_pio, port_base, page_address(sg->page) + sg->offset, sg->length);
 			}
 			REG0(port_base);
 		}
drivers/scsi/qla1280.c +37 -29

150 lines not on this page · raw message

drivers/scsi/qla2xxx/qla_iocb.c +3 -6
index c5b3c61..10251bf 100644
@@ -671,12 +671,11 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
 
 	/* Load data segments */
 	if (cmd->use_sg != 0) {
+		struct	scatterlist *sgl = cmd->request_buffer;
 		struct	scatterlist *cur_seg;
-		struct	scatterlist *end_seg;
+		int i;
 
-		cur_seg = (struct scatterlist *)cmd->request_buffer;
-		end_seg = cur_seg + tot_dsds;
-		while (cur_seg < end_seg) {
+		for_each_sg(sgl, cur_seg, tot_dsds, i) {
 			dma_addr_t	sle_dma;
 			cont_a64_entry_t *cont_pkt;
 
@@ -696,8 +695,6 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
 			*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
 			*cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg));
 			avail_dsds--;
-
-			cur_seg++;
 		}
 	} else {
 		*cur_dsd++ = cpu_to_le32(LSD(sp->dma_handle));
drivers/scsi/qla4xxx/ql4_iocb.c +3 -5
index a216a17..82a894b 100644
@@ -156,12 +156,11 @@ static void qla4xxx_build_scsi_iocbs(struct srb *srb,
 
 	/* Load data segments */
 	if (cmd->use_sg) {
+		struct scatterlist *sgl = cmd->request_buffer;
 		struct scatterlist *cur_seg;
-		struct scatterlist *end_seg;
+		int i;
 
-		cur_seg = (struct scatterlist *)cmd->request_buffer;
-		end_seg = cur_seg + tot_dsds;
-		while (cur_seg < end_seg) {
+		for_each_sg(sgl, cur_seg, tot_dsds, i) {
 			dma_addr_t sle_dma;
 
 			/* Allocate additional continuation packets? */
@@ -182,7 +181,6 @@ static void qla4xxx_build_scsi_iocbs(struct srb *srb,
 			avail_dsds--;
 
 			cur_dsd++;
-			cur_seg++;
 		}
 	} else {
 		cur_dsd->base.addrLow = cpu_to_le32(LSDW(srb->dma_handle));
drivers/scsi/qlogicfas408.c +5 -4
index 2e7db18..ccc7d3f 100644
@@ -315,18 +315,19 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
 			ql_pdma(priv, phase, cmd->request_buffer,
 				cmd->request_bufflen);
 		else {
+			struct scatterlist *sg;
+
 			sgcount = cmd->use_sg;
 			sglist = cmd->request_buffer;
-			while (sgcount--) {
+			for_each_sg(sglist, sg, sgcount, i) {
 				if (priv->qabort) {
 					REG0;
 					return ((priv->qabort == 1 ?
 						DID_ABORT : DID_RESET) << 16);
 				}
-				buf = page_address(sglist->page) + sglist->offset;
-				if (ql_pdma(priv, phase, buf, sglist->length))
+				buf = page_address(sg->page) + sg->offset;
+				if (ql_pdma(priv, phase, buf, sg->length))
 					break;
-				sglist++;
 			}
 		}
 		REG0;
drivers/scsi/qlogicpti.c +8 -7
index c4195ea..e36e6cd 100644
@@ -868,7 +868,7 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
 			   struct qlogicpti *qpti, u_int in_ptr, u_int out_ptr)
 {
 	struct dataseg *ds;
-	struct scatterlist *sg;
+	struct scatterlist *sg, *s;
 	int i, n;
 
 	if (Cmnd->use_sg) {
@@ -884,11 +884,12 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
 		n = sg_count;
 		if (n > 4)
 			n = 4;
-		for (i = 0; i < n; i++, sg++) {
-			ds[i].d_base = sg_dma_address(sg);
-			ds[i].d_count = sg_dma_len(sg);
+		for_each_sg(sg, s, n, i) {
+			ds[i].d_base = sg_dma_address(s);
+			ds[i].d_count = sg_dma_len(g);
 		}
 		sg_count -= 4;
+		sg = s;
 		while (sg_count > 0) {
 			struct Continuation_Entry *cont;
 
@@ -907,9 +908,9 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
 			n = sg_count;
 			if (n > 7)
 				n = 7;
-			for (i = 0; i < n; i++, sg++) {
-				ds[i].d_base = sg_dma_address(sg);
-				ds[i].d_count = sg_dma_len(sg);
+			for_each_sg(sg, s, n, i) {
+				ds[i].d_base = sg_dma_address(s);
+				ds[i].d_count = sg_dma_len(s);
 			}
 			sg_count -= n;
 		}
drivers/scsi/scsi_debug.c +16 -13
index 06229f2..0ef1310 100644
@@ -38,6 +38,7 @@
 #include <linux/proc_fs.h>
 #include <linux/vmalloc.h>
 #include <linux/moduleparam.h>
+#include <linux/scatterlist.h>
 
 #include <linux/blkdev.h>
 #include "scsi.h"
@@ -600,7 +601,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 	int k, req_len, act_len, len, active;
 	void * kaddr;
 	void * kaddr_off;
-	struct scatterlist * sgpnt;
+	struct scatterlist * sgpnt, * sg;
 
 	if (0 == scp->request_bufflen)
 		return 0;
@@ -621,14 +622,15 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 	}
 	sgpnt = (struct scatterlist *)scp->request_buffer;
 	active = 1;
-	for (k = 0, req_len = 0, act_len = 0; k < scp->use_sg; ++k, ++sgpnt) {
+	req_len = act_len = 0;
+	for_each_sg(sgpnt, sg, scp->use_sg, k) {
 		if (active) {
 			kaddr = (unsigned char *)
-				kmap_atomic(sgpnt->page, KM_USER0);
+				kmap_atomic(sg->page, KM_USER0);
 			if (NULL == kaddr)
 				return (DID_ERROR << 16);
-			kaddr_off = (unsigned char *)kaddr + sgpnt->offset;
-			len = sgpnt->length;
+			kaddr_off = (unsigned char *)kaddr + sg->offset;
+			len = sg->length;
 			if ((req_len + len) > arr_len) {
 				active = 0;
 				len = arr_len - req_len;
@@ -637,7 +639,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 			kunmap_atomic(kaddr, KM_USER0);
 			act_len += len;
 		}
-		req_len += sgpnt->length;
+		req_len += sg->length;
 	}
 	if (scp->resid)
 		scp->resid -= act_len;
@@ -653,7 +655,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 	int k, req_len, len, fin;
 	void * kaddr;
 	void * kaddr_off;
-	struct scatterlist * sgpnt;
+	struct scatterlist * sg;
 
 	if (0 == scp->request_bufflen)
 		return 0;
@@ -668,13 +670,14 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 		memcpy(arr, scp->request_buffer, len);
 		return len;
 	}
-	sgpnt = (struct scatterlist *)scp->request_buffer;
-	for (k = 0, req_len = 0, fin = 0; k < scp->use_sg; ++k, ++sgpnt) {
-		kaddr = (unsigned char *)kmap_atomic(sgpnt->page, KM_USER0);
+	sg = (struct scatterlist *)scp->request_buffer;
+	req_len = fin = 0;
+	for (k = 0; k < scp->use_sg; ++k, sg = sg_next(sg)) {
+		kaddr = (unsigned char *)kmap_atomic(sg->page, KM_USER0);
 		if (NULL == kaddr)
 			return -1;
-		kaddr_off = (unsigned char *)kaddr + sgpnt->offset;
-		len = sgpnt->length;
+		kaddr_off = (unsigned char *)kaddr + sg->offset;
+		len = sg->length;
 		if ((req_len + len) > max_arr_len) {
 			len = max_arr_len - req_len;
 			fin = 1;
@@ -683,7 +686,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
 		kunmap_atomic(kaddr, KM_USER0);
 		if (fin)
 			return req_len + len;
-		req_len += sgpnt->length;
+		req_len += sg->length;
 	}
 	return req_len;
 }
drivers/scsi/scsi_lib.c +167 -60

340 lines not on this page · raw message

drivers/scsi/scsi_tgt_lib.c +2 -2
index 2570f48..d6e58e5 100644
@@ -329,7 +329,7 @@ static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd)
 	scsi_tgt_uspace_send_status(cmd, tcmd->tag);
 
 	if (cmd->request_buffer)
-		scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
+		scsi_free_sgtable(cmd);
 
 	queue_work(scsi_tgtd, &tcmd->work);
 }
@@ -370,7 +370,7 @@ static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 	}
 
 	eprintk("cmd %p cnt %d\n", cmd, cmd->use_sg);
-	scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len);
+	scsi_free_sgtable(cmd);
 	return -EINVAL;
 }
 
drivers/scsi/sg.c +8 -8
index 0c691a6..0d67fa2 100644
@@ -1168,7 +1168,7 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
 	sg = rsv_schp->buffer;
 	sa = vma->vm_start;
 	for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
-	     ++k, ++sg) {
+	     ++k, sg = sg_next(sg)) {
 		len = vma->vm_end - sa;
 		len = (len < sg->length) ? len : sg->length;
 		if (offset < len) {
@@ -1212,7 +1212,7 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
 	sa = vma->vm_start;
 	sg = rsv_schp->buffer;
 	for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
-	     ++k, ++sg) {
+	     ++k, sg = sg_next(sg)) {
 		len = vma->vm_end - sa;
 		len = (len < sg->length) ? len : sg->length;
 		sa += len;
@@ -1866,7 +1866,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
 	}
 	for (k = 0, sg = schp->buffer, rem_sz = blk_size;
 	     (rem_sz > 0) && (k < mx_sc_elems);
-	     ++k, rem_sz -= ret_sz, ++sg) {
+	     ++k, rem_sz -= ret_sz, sg = sg_next(sg)) {
 		
 		num = (rem_sz > scatter_elem_sz_prev) ?
 		      scatter_elem_sz_prev : rem_sz;
@@ -1939,7 +1939,7 @@ sg_write_xfer(Sg_request * srp)
 		if (res)
 			return res;
 
-		for (; p; ++sg, ksglen = sg->length,
+		for (; p; sg = sg_next(sg), ksglen = sg->length,
 		     p = page_address(sg->page)) {
 			if (usglen <= 0)
 				break;
@@ -2018,7 +2018,7 @@ sg_remove_scat(Sg_scatter_hold * schp)
 			int k;
 
 			for (k = 0; (k < schp->k_use_sg) && sg->page;
-			     ++k, ++sg) {
+			     ++k, sg = sg_next(sg)) {
 				SCSI_LOG_TIMEOUT(5, printk(
 				    "sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
 				    k, sg->page, sg->length));
@@ -2071,7 +2071,7 @@ sg_read_xfer(Sg_request * srp)
 		if (res)
 			return res;
 
-		for (; p; ++sg, ksglen = sg->length,
+		for (; p; sg = sg_next(sg), ksglen = sg->length,
 		     p = page_address(sg->page)) {
 			if (usglen <= 0)
 				break;
@@ -2118,7 +2118,7 @@ sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
 	if ((!outp) || (num_read_xfer <= 0))
 		return 0;
 
-	for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, ++sg) {
+	for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, sg = sg_next(sg)) {
 		num = sg->length;
 		if (num > num_read_xfer) {
 			if (__copy_to_user(outp, page_address(sg->page),
@@ -2168,7 +2168,7 @@ sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size)
 	SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size));
 	rem = size;
 
-	for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sg) {
+	for (k = 0; k < rsv_schp->k_use_sg; ++k, sg = sg_next(sg)) {
 		num = sg->length;
 		if (rem <= num) {
 			sfp->save_scat_len = num;
drivers/scsi/sym53c416.c +3 -6
index 2ca9505..06c765c 100644
@@ -332,7 +332,7 @@ static irqreturn_t sym53c416_intr_handle(int irq, void *dev_id)
 	int i;
 	unsigned long flags = 0;
 	unsigned char status_reg, pio_int_reg, int_reg;
-	struct scatterlist *sglist;
+	struct scatterlist *sglist, *sg;
 	unsigned int sgcount;
 	unsigned int tot_trans = 0;
 
@@ -437,11 +437,8 @@ static irqreturn_t sym53c416_intr_handle(int irq, void *dev_id)
 				{
 					sgcount = current_command->use_sg;
 					sglist = current_command->request_buffer;
-					while(sgcount--)
-					{
-						tot_trans += sym53c416_write(base, SG_ADDRESS(sglist), sglist->length);
-						sglist++;
-					}
+					for_each_sg(sglist, sg, sgcount, i)
+						tot_trans += sym53c416_write(base, SG_ADDRESS(sg), sg->length);
 				}
 				if(tot_trans < current_command->underflow)
 					printk(KERN_WARNING "sym53c416: Underflow, wrote %d bytes, request for %d bytes.\n", tot_trans, current_command->underflow);
drivers/scsi/sym53c8xx_2/sym_glue.c +4 -3
index 4d78c7e..f39e3ec 100644
@@ -371,6 +371,7 @@ static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd
 		segment = sym_scatter_no_sglist(np, cp, cmd);
 	else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) {
 		struct scatterlist *scatter = (struct scatterlist *)cmd->request_buffer;
+		struct scatterlist *sg;
 		struct sym_tcb *tp = &np->target[cp->target];
 		struct sym_tblmove *data;
 
@@ -381,9 +382,9 @@ static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd
 
 		data = &cp->phys.data[SYM_CONF_MAX_SG - use_sg];
 
-		for (segment = 0; segment < use_sg; segment++) {
-			dma_addr_t baddr = sg_dma_address(&scatter[segment]);
-			unsigned int len = sg_dma_len(&scatter[segment]);
+		for_each_sg(scatter, sg, use_sg, segment) {
+			dma_addr_t baddr = sg_dma_address(sg);
+			unsigned int len = sg_dma_len(sg);
 
 			if ((len & 1) && (tp->head.wval & EWS)) {
 				len++;
drivers/scsi/u14-34f.c +5 -5
index 3de08a1..db17ba4 100644
@@ -1111,7 +1111,7 @@ static int u14_34f_detect(struct scsi_host_template *tpnt) {
 static void map_dma(unsigned int i, unsigned int j) {
    unsigned int data_len = 0;
    unsigned int k, count, pci_dir;
-   struct scatterlist *sgpnt;
+   struct scatterlist *sgpnt, *sg;
    struct mscp *cpp;
    struct scsi_cmnd *SCpnt;
 
@@ -1140,10 +1140,10 @@ static void map_dma(unsigned int i, unsigned int j) {
    sgpnt = (struct scatterlist *) SCpnt->request_buffer;
    count = pci_map_sg(HD(j)->pdev, sgpnt, SCpnt->use_sg, pci_dir);
 
-   for (k = 0; k < count; k++) {
-      cpp->sglist[k].address = H2DEV(sg_dma_address(&sgpnt[k]));
-      cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(&sgpnt[k]));
[… more lines in the raw message]

Lines of this file are not shown. View the raw message.

drivers/scsi/ultrastor.c +5 -5
index 56906ab..1b721ec 100644

Lines of this file are not shown. View the raw message.

drivers/scsi/wd7000.c +4 -3
index 30be765..85aaa5e 100644

Lines of this file are not shown. View the raw message.

drivers/usb/storage/alauda.c +10 -6
index 4d3cbb1..8d3711a 100644

Lines of this file are not shown. View the raw message.

drivers/usb/storage/datafab.c +6 -4
index c87ad1b..579e9f5 100644

Lines of this file are not shown. View the raw message.

drivers/usb/storage/jumpshot.c +6 -4
index 003fcf5..61097cb 100644

Lines of this file are not shown. View the raw message.

drivers/usb/storage/protocol.c +11 -9
index 9ad3042..cc8f7c5 100644

Lines of this file are not shown. View the raw message.

drivers/usb/storage/protocol.h +1 -1
index 845bed4..8737a36 100644

Lines of this file are not shown. View the raw message.

drivers/usb/storage/sddr09.c +10 -6
index b2ed2a3..b12202c 100644

Lines of this file are not shown. View the raw message.

drivers/usb/storage/sddr55.c +10 -6
index 0b1b5b5..d43a341 100644

Lines of this file are not shown. View the raw message.

drivers/usb/storage/shuttle_usbat.c +8 -9
index 5e27297..a0ff394 100644

Lines of this file are not shown. View the raw message.

include/asm-i386/dma-mapping.h +7 -6
index 183eebe..a956ec1 100644

Lines of this file are not shown. View the raw message.

include/asm-i386/scatterlist.h +2 -0
index d7e45a8..bd5164a 100644

Lines of this file are not shown. View the raw message.

include/asm-x86_64/dma-mapping.h +1 -2
index 6897e2a..ecd0f61 100644

Lines of this file are not shown. View the raw message.

include/asm-x86_64/scatterlist.h +2 -0
index eaf7ada..ef3986b 100644

Lines of this file are not shown. View the raw message.

include/linux/i2o.h +1 -1
index 52f53e2..0ae1dcf 100644

Lines of this file are not shown. View the raw message.

include/linux/ide.h +1 -1
index df4e6a5..4123668 100644

Lines of this file are not shown. View the raw message.

include/linux/libata.h +10 -6
index 7906d75..8fad10e 100644

Lines of this file are not shown. View the raw message.

include/linux/scatterlist.h +57 -0

57 lines not on this page · raw message

include/scsi/scsi.h +0 -7
index 9f8f80a..702fcfe 100644

Lines of this file are not shown. View the raw message.

include/scsi/scsi_cmnd.h +2 -1
index a2e0c10..fc649af 100644

Lines of this file are not shown. View the raw message.

lib/swiotlb.c +12 -7
index 10c13ad..1f658e4 100644

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Signature · 1 line
Jens Axboe

Part of the diff is not shown here. View the raw message.

#1 lore raw
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ‘sym_scatter’:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ‘for_each_sg’ drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ‘;’ before ‘{’ token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ‘tp’ make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

drivers/scsi/qla2xxx/qla_iocb.c: In function ‘qla24xx_build_scsi_iocbs’:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ‘for_each_sg’
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ‘;’ before ‘{’ token

Thanks,
Badari

author
#2 lore raw
Quoted 17 lines · Badari Pulavarty
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ???sym_scatter???:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ???for_each_sg??? drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ???;??? before ???{??? token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ???tp??? make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

Quoted 5 lines

drivers/scsi/qla2xxx/qla_iocb.c: In function ???qla24xx_build_scsi_iocbs???:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ???for_each_sg???
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ???;??? before ???{??? token

Thanks, will fix those. What arch? I tested it here.

Signature · 1 line
Jens Axboe
#3 lore raw
Quoted 18 lines · Jens Axboe
Quoted 17 lines · Badari Pulavarty
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ???sym_scatter???:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ???for_each_sg??? drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ???;??? before ???{??? token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ???tp??? make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

Quoted 7 lines
Quoted 5 lines

drivers/scsi/qla2xxx/qla_iocb.c: In function ???qla24xx_build_scsi_iocbs???:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ???for_each_sg???
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ???;??? before ???{??? token

Thanks, will fix those. What arch? I tested it here.

I am playing with them on ppc64.

Thanks,
Badari

author
#4 lore raw
Quoted 25 lines · Badari Pulavarty
Quoted 24 lines · Jens Axboe
Quoted 22 lines · Badari Pulavarty
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ???sym_scatter???:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ???for_each_sg??? drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ???;??? before ???{??? token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ???tp??? make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

drivers/scsi/qla2xxx/qla_iocb.c: In function ???qla24xx_build_scsi_iocbs???:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ???for_each_sg???
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ???;??? before ???{??? token

Quoted 3 lines
Quoted 1 line

Thanks, will fix those. What arch? I tested it here.

I am playing with them on ppc64.

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

git://git.kernel.dk/data/git/linux-2.6-block.git

I can mail you an updated patch, if you want.

Signature · 1 line
Jens Axboe
author
#5 lore raw
Quoted 26 lines · Jens Axboe
Quoted 25 lines · Badari Pulavarty
Quoted 24 lines · Jens Axboe
Quoted 22 lines · Badari Pulavarty
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ???sym_scatter???:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ???for_each_sg??? drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ???;??? before ???{??? token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ???tp??? make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

drivers/scsi/qla2xxx/qla_iocb.c: In function ???qla24xx_build_scsi_iocbs???:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ???for_each_sg???
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ???;??? before ???{??? token

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

Thanks, will fix those. What arch? I tested it here.

I am playing with them on ppc64.

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

A little teaser for those that haven't tried it yet. This is the blktrace stats of doing a dd from a device and piping to md5sum. Just meant to test that I got the same data back with chained sglists.

Snips from the blktrace data:

  8,16   2     1302    14.958707808     0  C   R 983040 + 10240 [0]
  8,16   2     1303    14.959619712     0  D   R 1005568 + 13312 [swapper]
  8,16   2     1304    15.066257952     0  C   R 993280 + 12288 [0]
  8,16   2     1305    15.067238272     0  D   R 1018880 + 13312 [swapper]

That's completion of a 5120kb request, dispatch of a 6656kb request, completion of a 6144kb request, and finally dispatch of a 6656kb request again. Average io size for reading half a gig of data:

Read Dispatches: 110, 524,288KiB

or ~4766kb average IO size. 6656 are the largest requests in this test, it's running into the hw sg limit at that point. Just doing a plain O_DIRECT dd from the device makes basically all requests reach the max, giving an average io size above 6mb/request.

Signature · 1 line
Jens Axboe
#6 lore raw
In reply to Jens Axboe
Quoted 28 lines · Jens Axboe
Quoted 27 lines · Badari Pulavarty
Quoted 25 lines · Jens Axboe
Quoted 17 lines · Badari Pulavarty
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ???sym_scatter???:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ???for_each_sg??? drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ???;??? before ???{??? token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ???tp??? make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

Quoted 5 lines

drivers/scsi/qla2xxx/qla_iocb.c: In function ???qla24xx_build_scsi_iocbs???:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ???for_each_sg???
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ???;??? before ???{??? token

Thanks, will fix those. What arch? I tested it here.

Quoted 9 lines
Quoted 1 line

I am playing with them on ppc64.

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

git://git.kernel.dk/data/git/linux-2.6-block.git

I can mail you an updated patch, if you want.

paniced my amd64 box on boot :(

Unable to handle kernel NULL pointer dereference at 000000000000001e
RIP:
 [<ffffffff80381aa1>] blk_rq_map_sg+0x71/0x1b0
PGD 0
Oops: 0000 [1] SMP
CPU 0
Modules linked in:
Pid: 1, comm: swapper Not tainted 2.6.22-rc1 #2
RIP: 0010:[<ffffffff80381aa1>]  [<ffffffff80381aa1>] blk_rq_map_sg
+0x71/0x1b0
RSP: 0000:ffff810180239330  EFLAGS: 00010287
RAX: 0000000179d0ffff RBX: ffff8101bf204320 RCX: 0000000000001000
RDX: ffff810179c62000 RSI: ffff8101df507780 RDI: 0000000000179d00
#7 lore raw
In reply to Jens Axboe
Quoted 28 lines · Jens Axboe
Quoted 27 lines · Badari Pulavarty
Quoted 25 lines · Jens Axboe
Quoted 17 lines · Badari Pulavarty
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ???sym_scatter???:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ???for_each_sg??? drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ???;??? before ???{??? token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ???tp??? make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

Quoted 5 lines

drivers/scsi/qla2xxx/qla_iocb.c: In function ???qla24xx_build_scsi_iocbs???:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ???for_each_sg???
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ???;??? before ???{??? token

Thanks, will fix those. What arch? I tested it here.

Quoted 8 lines
Quoted 1 line

I am playing with them on ppc64.

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

git://git.kernel.dk/data/git/linux-2.6-block.git

I can mail you an updated patch, if you want.

Here is the whole panic stack..

VFS: Mounted root (reiserfs filesystem) readonly.
Freeing unused kernel memory: 356k freed

Unable to handle kernel paging request at 00000000464b7948 RIP:
 [<ffffffff80381aa1>] blk_rq_map_sg+0x71/0x1b0
PGD 1df350067 PUD 0
Oops: 0000 [1] SMP
CPU 3
Modules linked in:
Pid: 1, comm: init Not tainted 2.6.22-rc1 #2
RIP: 0010:[<ffffffff80381aa1>]  [<ffffffff80381aa1>] blk_rq_map_sg
+0x71/0x1b0
RSP: 0000:ffff8101a02390e8  EFLAGS: 00010206
RAX: 00000001df36a000 RBX: ffff8101df2efce0 RCX: 00000001df446000
RDX: 0000000000000000 RSI: ffff8101df2eb780 RDI: 00000000001df36a
RBP: ffff8101a0239148 R08: 00000000000004e2 R09: 0000000000000000
R10: ffff8101df2eb780 R11: 0000000000000001 R12: 00000000464b7928
R13: 0000000000001000 R14: 000000000000000e R15: ffff8101df2efcd0
FS:  0000000000000000(0000) GS:ffff8101c0223300(0000)

knlGS:0000000000000000
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 00000000464b7948 CR3: 000000017a397000 CR4: 00000000000006e0 Process init (pid: 1, threadinfo ffff8101a0238000, task ffff81018023a000)

Stack:  0000000000000001 ffff810179c58000 00000001df446000
ffff810179c56060
 ffff8101df2eb780 00000004a02393b8 0100000000000001 ffff8101df2b4000
 ffffffff8078a500 ffff810179c56000 ffffffff8078a500 ffff8101df2b4000
Call Trace:
 [<ffffffff8042faf2>] ide_map_sg+0x42/0xd0
 [<ffffffff804393aa>] ide_build_sglist+0x2a/0x90
 [<ffffffff8043943f>] ide_build_dmatable+0x2f/0x1a0
 [<ffffffff804395f4>] ide_dma_setup+0x44/0xe0
 [<ffffffff8043cdf9>] ide_do_rw_disk+0x349/0x510
 [<ffffffff80430442>] ide_do_request+0x622/0xb40
 [<ffffffff802393a6>] lock_timer_base+0x36/0x70
 [<ffffffff802397cb>] del_timer+0x6b/0x70
 [<ffffffff80430d0d>] do_ide_request+0x1d/0x20
 [<ffffffff80384155>] __generic_unplug_device+0x25/0x30
 [<ffffffff80384315>] blk_start_queueing+0x25/0x30
 [<ffffffff8038c97b>] cfq_insert_request+0x36b/0x380
 [<ffffffff80380980>] elv_insert+0x130/0x1a0
 [<ffffffff80380a58>] __elv_add_request+0x68/0xc0
 [<ffffffff80385383>] __make_request+0xd3/0x590
 [<ffffffff80382db8>] generic_make_request+0x198/0x240
 [<ffffffff802af069>] bio_alloc_bioset+0xa9/0x120
 [<ffffffff80385a52>] submit_bio+0x62/0xe0
 [<ffffffff802b29b2>] mpage_bio_submit+0x22/0x30
 [<ffffffff802b358d>] do_mpage_readpage+0x49d/0x590
 [<ffffffff8026641a>] __inc_zone_page_state+0x2a/0x30
 [<ffffffff802b3898>] mpage_readpages+0x88/0x160
 [<ffffffff802e4b50>] reiserfs_get_block+0x0/0x1250
 [<ffffffff802e4b50>] reiserfs_get_block+0x0/0x1250
 [<ffffffff802e394a>] reiserfs_readpages+0x1a/0x20
 [<ffffffff8026178f>] __do_page_cache_readahead+0x1af/0x2c0
 [<ffffffff8025f7ae>] __alloc_pages+0x6e/0x330
 [<ffffffff80261ca9>] do_page_cache_readahead+0x59/0x80
 [<ffffffff8025cc99>] filemap_nopage+0x239/0x2f0
 [<ffffffff80269100>] __handle_mm_fault+0x1d0/0xba0
 [<ffffffff8021c67c>] do_page_fault+0x1dc/0x950
 [<ffffffff8025f7ae>] __alloc_pages+0x6e/0x330
 [<ffffffff8026573d>] vma_prio_tree_insert+0x2d/0x50
 [<ffffffff8026de22>] vma_link+0xb2/0x140
 [<ffffffff8026d14b>] __vma_link_rb+0x2b/0x30
 [<ffffffff80505bed>] error_exit+0x0/0x84
 [<ffffffff80395aba>] __clear_user+0x1a/0x40
 [<ffffffff80395bfb>] clear_user+0x2b/0x40
 [<ffffffff802bef91>] padzero+0x21/0x30
 [<ffffffff802c0abf>] load_elf_binary+0xbbf/0x1ec0
 [<ffffffff8025f7ae>] __alloc_pages+0x6e/0x330
 [<ffffffff8025f7ae>] __alloc_pages+0x6e/0x330
 [<ffffffff80279c5a>] alloc_pages_current+0x5a/0x90
 [<ffffffff8028aac2>] copy_strings+0x122/0x220
 [<ffffffff8028adaf>] search_binary_handler+0xaf/0x210
 [<ffffffff8028cbff>] do_execve+0x25f/0x290
 [<ffffffff80395bba>] strncpy_from_user+0x3a/0x50
 [<ffffffff80208736>] sys_execve+0x46/0xb0
 [<ffffffff8020a994>] kernel_execve+0x64/0xd0
 [<ffffffff8020707e>] run_init_process+0x1e/0x20
 [<ffffffff8020711f>] init_post+0x9f/0xf0
 [<ffffffff806aeaff>] kernel_init+0x23f/0x330
 [<ffffffff8020a928>] child_rip+0xa/0x12
 [<ffffffff806ae8c0>] kernel_init+0x0/0x330
 [<ffffffff8020a91e>] child_rip+0x0/0x12


Code: 49 8b 44 24 20 49 8d 4c 24 20 48 89 c2 48 83 e2 fe a8 01 48
RIP  [<ffffffff80381aa1>] blk_rq_map_sg+0x71/0x1b0
 RSP <ffff8101a02390e8>
CR2: 00000000464b7948
Kernel panic - not syncing: Attempted to kill init!

Thanks,
Badari

author
#8 lore raw
Quoted 34 lines · Badari Pulavarty
Quoted 33 lines · Jens Axboe
Quoted 25 lines · Badari Pulavarty
Quoted 24 lines · Jens Axboe
Quoted 22 lines · Badari Pulavarty
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ???sym_scatter???:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ???for_each_sg??? drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ???;??? before ???{??? token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ???tp??? make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

drivers/scsi/qla2xxx/qla_iocb.c: In function ???qla24xx_build_scsi_iocbs???:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ???for_each_sg???
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ???;??? before ???{??? token

Quoted 3 lines
Quoted 1 line

Thanks, will fix those. What arch? I tested it here.

I am playing with them on ppc64.

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

Quoted 6 lines
Quoted 3 lines

git://git.kernel.dk/data/git/linux-2.6-block.git

I can mail you an updated patch, if you want.

Here is the whole panic stack..

Thanks will fix that up, the IDE part is totally untested. Can you try and backout this patch and see if it boots?

drivers/ide/cris/ide-cris.c +2 -1
index ca0341c..3565c76 100644
@@ -951,7 +951,8 @@ static int cris_ide_build_dmatable (ide_drive_t *drive)
 		/* group sequential buffers into one large buffer */
 		addr = page_to_phys(sg->page) + sg->offset;
 		size = sg_dma_len(sg);
-		while (sg++, --i) {
+		while (--i) {
+			sg = sg_next(sg);
 			if ((addr + size) != page_to_phys(sg->page) + sg->offset)
 				break;
 			size += sg_dma_len(sg);
drivers/ide/ide-dma.c +1 -1
index b77b7d1..aa13309 100644
@@ -292,7 +292,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
 			}
 		}
 
-		sg++;
+		sg = sg_next(sg);
 		i--;
 	}
 
drivers/ide/ide-taskfile.c +13 -4
index 30175c7..412ba5e 100644
@@ -259,6 +259,7 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
 {
 	ide_hwif_t *hwif = drive->hwif;
 	struct scatterlist *sg = hwif->sg_table;
+	struct scatterlist *cursg = hwif->cursg;
 	struct page *page;
 #ifdef CONFIG_HIGHMEM
 	unsigned long flags;
@@ -266,8 +267,14 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
 	unsigned int offset;
 	u8 *buf;
 
-	page = sg[hwif->cursg].page;
-	offset = sg[hwif->cursg].offset + hwif->cursg_ofs * SECTOR_SIZE;
+	cursg = hwif->cursg;
+	if (!cursg) {
+		cursg = sg;
+		hwif->cursg = sg;
+	}
+
+	page = cursg->page;
+	offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
 
 	/* get the current page and offset */
 	page = nth_page(page, (offset >> PAGE_SHIFT));
@@ -281,8 +288,8 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
 	hwif->nleft--;
 	hwif->cursg_ofs++;
 
-	if ((hwif->cursg_ofs * SECTOR_SIZE) == sg[hwif->cursg].length) {
-		hwif->cursg++;
+	if ((hwif->cursg_ofs * SECTOR_SIZE) == cursg->length) {
+		hwif->cursg = sg_next(hwif->cursg);
 		hwif->cursg_ofs = 0;
 	}
 
@@ -363,6 +370,8 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
 
 static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
 {
+	HWIF(drive)->cursg = NULL;
+
 	if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
 		ide_task_t *task = rq->special;
 
drivers/ide/mips/au1xxx-ide.c +1 -1
index ca95e99..35b0d1e 100644
@@ -324,7 +324,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
 			cur_addr += tc;
 			cur_len -= tc;
 		}
-		sg++;
+		sg = sg_next(sg);
 		i--;
 	}
 
drivers/ide/pci/sgiioc4.c +1 -1
index d3185e2..511e734 100644
@@ -531,7 +531,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
 			}
 		}
 
-		sg++;
+		sg = sg_next(sg);
 		i--;
 	}
 
drivers/ide/ppc/pmac.c +1 -1
index 45fc36f..2a7555d 100644
@@ -1648,7 +1648,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
 			cur_len -= tc;
 			++table;
 		}
-		sg++;
+		sg = sg_next(sg);
 		i--;
 	}
 
include/linux/ide.h +1 -1
index 07aba87..fe81b05 100644
@@ -764,7 +764,7 @@ typedef struct hwif_s {
 
 	unsigned int nsect;
 	unsigned int nleft;
-	unsigned int cursg;
+	struct scatterlist *cursg;
 	unsigned int cursg_ofs;
 
 	int		rqsize;		/* max sectors per request */
Signature · 1 line
Jens Axboe
#9 lore raw

On Thu, 2007-05-17 at 08:27 +0200, Jens Axboe wrote:
..

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

git://git.kernel.dk/data/git/linux-2.6-block.git

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

I can mail you an updated patch, if you want.

Here is the whole panic stack..

Thanks will fix that up, the IDE part is totally untested. Can you try and backout this patch and see if it boots?

Yes. It boots fine with following backed out.

Looking at the code ide_probe.c: hwif_init() is doing

        hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
                                 GFP_KERNEL);

blk_rq_map_sg() is looking for the chaining info and going over end of the allocation.

Thanks,
Badari

#14 lore raw
In reply to Jens Axboe
Quoted 37 lines · Jens Axboe
Quoted 36 lines · Badari Pulavarty
Quoted 35 lines · Jens Axboe
Quoted 25 lines · Badari Pulavarty
Quoted 24 lines · Jens Axboe
Quoted 22 lines · Badari Pulavarty
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ???sym_scatter???:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ???for_each_sg??? drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ???;??? before ???{??? token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ???tp??? make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

drivers/scsi/qla2xxx/qla_iocb.c: In function ???qla24xx_build_scsi_iocbs???:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ???for_each_sg???
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ???;??? before ???{??? token

Quoted 3 lines
Quoted 1 line

Thanks, will fix those. What arch? I tested it here.

I am playing with them on ppc64.

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

git://git.kernel.dk/data/git/linux-2.6-block.git

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

I can mail you an updated patch, if you want.

Here is the whole panic stack..

Thanks will fix that up, the IDE part is totally untested. Can you try and backout this patch and see if it boots?

I increased max_segments to 1024 on my qla2200 attached disks and simple "dd" (direct read) resulted in following:

elm3b29:/sys/block/sdd/queue # echo 1024 > max_segments elm3b29:/sys/block/sdd/queue # cat max_hw_sectors_kb > max_sectors_kb elm3b29:/mnt # dd iflag=direct if=./z of=/dev/null bs=512M

Unable to handle kernel paging request at 0000000000001008 RIP:
 [<ffffffff8025e7af>] __rmqueue+0x6f/0x120
PGD 100921067 PUD 1057f9067 PMD 0
Oops: 0002 [1] SMP
CPU 0
Modules linked in: jfs hfs vfat fat sg sd_mod qla2xxx firmware_class
scsi_transport_fc scsi_mod ipv6 thermal processor fan button battery ac
dm_mod floppy parport_pc lp parport
Pid: 4329, comm: dd Tainted: G   M   2.6.22-rc1 #4
RIP: 0010:[<ffffffff8025e7af>]  [<ffffffff8025e7af>] __rmqueue
+0x6f/0x120
RSP: 0018:ffff8101bdcab948  EFLAGS: 00010093
RAX: ffff81017e644148 RBX: 0000000000000002 RCX: 0000000000001000
RDX: ffff810000011c80 RSI: 0000000000000000 RDI: ffff810000011a00
RBP: ffff8101bdcab968 R08: ffff81017a801142 R09: 0000000000000000
R10: 0000000000078e7a R11: 0000000000000002 R12: ffff810000011c80
R13: 0000000000000000 R14: ffff81017e644120 R15: ffff810000011a00
FS:  00002b53c78cef20(0000) GS:ffffffff8063b000(0000)

knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000001008 CR3: 0000000102707000 CR4: 00000000000006e0 Process dd (pid: 4329, threadinfo ffff8101bdcaa000, task ffff8101bf4ff440)

Stack:  ffff81017a801110 0000000000000012 0000000000000012
ffff81017a801100
 ffff8101bdcaba08 ffffffff8025f47d 0000000000000001 ffff810000012e68
 000000445f7ebe38 ffff810000012e60 000280d200000000 ffff810000012e68
Call Trace:
 [<ffffffff8025f47d>] get_page_from_freelist+0x31d/0x510
 [<ffffffff8025f7ae>] __alloc_pages+0x6e/0x330
 [<ffffffff80278b4a>] alloc_page_vma+0x4a/0xa0
 [<ffffffff802698e7>] __handle_mm_fault+0x9b7/0xba0
 [<ffffffff80268086>] follow_page+0x1b6/0x250
 [<ffffffff80269bdc>] get_user_pages+0x10c/0x3d0
 [<ffffffff802aee8e>] bio_add_page+0x2e/0x30
 [<ffffffff802b144b>] dio_get_page+0xbb/0x1b0
 [<ffffffff802b2148>] __blockdev_direct_IO+0x478/0xc20
 [<ffffffff881812e0>] :jfs:jfs_direct_IO+0x50/0x60
 [<ffffffff881818d0>] :jfs:jfs_get_block+0x0/0x230
 [<ffffffff8025b793>] generic_file_direct_IO+0x73/0x150
 [<ffffffff8025ce81>] generic_file_aio_read+0x131/0x170
 [<ffffffff802717b0>] page_add_new_anon_rmap+0x10/0x20
 [<ffffffff80269997>] __handle_mm_fault+0xa67/0xba0
 [<ffffffff802867d1>] do_sync_read+0xf1/0x130
 [<ffffffff80247fe9>] up_read+0x9/0x10
 [<ffffffff80244fc0>] autoremove_wake_function+0x0/0x40
 [<ffffffff80392a80>] __up_write+0xd0/0x130
 [<ffffffff80287101>] vfs_read+0xe1/0x190
 [<ffffffff802875b0>] sys_read+0x50/0x90
 [<ffffffff80209b0e>] system_call+0x7e/0x83


Code: 48 89 51 08 48 89 0a 48 c7 40 08 00 02 20 00 48 c7 00 00 01
RIP  [<ffffffff8025e7af>] __rmqueue+0x6f/0x120
 RSP <ffff8101bdcab948>
CR2: 0000000000001008
Unable to handle kernel paging request<0>Eeek! page_mapcount(page) went

negative! (-1)
page pfn = 10a738
page->flags = 14
page->count = 80287910
page->mapping = 0000000000000000
vma->vm_ops = _stext+0x7fdf9000/0x60
at 0000200000000018 RIP:
[<ffffffff80227485>] task_rq_lock+0x35/0x90
PGD 0

Oops: 0000 [2] SMP
CPU 2
Modules linked in: jfs hfs vfat fat sg sd_mod qla2xxx firmware_class
scsi_transport_fc scsi_mod ipv6 thermal processor fan button battery ac
dm_mod floppy parport_pc lp parport
Pid: 0, comm: swapper Tainted: G   M   2.6.22-rc1 #4
RIP: 0010:[<ffffffff80227485>]  [<ffffffff80227485>] task_rq_lock
+0x35/0x90
RSP: 0018:ffff810180247dc0  EFLAGS: 00010086
RAX: 0000200000000000 RBX: ffffffff80701780 RCX: ffff8101d9639cc8
RDX: 0000000000000000 RSI: ffff810180247e28 RDI: ffff8101dc810000
RBP: ffff810180247de0 R08: 0000000000000000 R09: ffffffff80701780
R10: ffff81021f90c000 R11: 0000000000000246 R12: ffffffff80701780
R13: ffff8101dc810000 R14: ffff810180247e28 R15: 0000000000000001
FS:  00002ae1c3672400(0000) GS:ffff8101a0220300(0000)

knlGS:00000000f7dfb6b0
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 0000200000000018 CR3: 000000019e8f4000 CR4: 00000000000006e0 Process swapper (pid: 0, threadinfo ffff81017ab6c000, task ffff8101c025a000)

Stack:  000000000000000f ffff8101dc810000 ffff8101a0011328
ffff8101a00112e0
 ffff810180247e60 ffffffff80229b3f 0000000100000002 0000000000000000
 0000000000000000 ffffffffffffffff 0000000000000000 0000000000000000
Call Trace:
 <IRQ>  [<ffffffff80229b3f>] try_to_wake_up+0x2f/0x4b0
 [<ffffffff802477a0>] hrtimer_wakeup+0x0/0x30
 [<ffffffff80229ff0>] wake_up_process+0x10/0x20
 [<ffffffff802477bd>] hrtimer_wakeup+0x1d/0x30
 [<ffffffff802479b4>] hrtimer_run_queues+0x114/0x180
 [<ffffffff80238ee8>] run_timer_softirq+0x28/0x1d0
 [<ffffffff80235734>] __do_softirq+0x74/0xf0
 [<ffffffff8020ac9c>] call_softirq+0x1c/0x30
 [<ffffffff8020ca1d>] do_softirq+0x3d/0x90
 [<ffffffff802355e5>] irq_exit+0x45/0x50
 [<ffffffff80216e15>] smp_apic_timer_interrupt+0x55/0x70
 [<ffffffff80208c60>] default_idle+0x0/0x50
 [<ffffffff8020a746>] apic_timer_interrupt+0x66/0x70
 <EOI>  [<ffffffff80208c8d>] default_idle+0x2d/0x50
 [<ffffffff80208532>] enter_idle+0x22/0x30
 [<ffffffff80208d0c>] cpu_idle+0x5c/0x80
 [<ffffffff806bbdd6>] start_secondary+0x256/0x360
 [<ffffffff80244bbd>] kthread+0x4d/0x80


Code: 8b 40 18 48 8b 04 c5 c0 fa 68 80 48 03 58 08 48 89 df e8 94
RIP  [<ffffffff80227485>] task_rq_lock+0x35/0x90
 RSP <ffff810180247dc0>
CR2: 0000200000000018
Kernel panic - not syncing: Aiee, killing interrupt handler!
author
#10 lore raw
In reply to Badari Pulavarty
Quoted 18 lines · Badari Pulavarty

On Thu, 2007-05-17 at 08:27 +0200, Jens Axboe wrote:
..

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

git://git.kernel.dk/data/git/linux-2.6-block.git

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

I can mail you an updated patch, if you want.

Here is the whole panic stack..

Thanks will fix that up, the IDE part is totally untested. Can you try and backout this patch and see if it boots?

Yes. It boots fine with following backed out.

Quoted 7 lines

Looking at the code ide_probe.c: hwif_init() is doing

        hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
                                 GFP_KERNEL);

blk_rq_map_sg() is looking for the chaining info and going over end of the allocation.

Hmm, looks ok, I'm guessing it's just missing a memset (or just turn it into a kzalloc())?

Signature · 1 line
Jens Axboe
author
#15 lore raw
In reply to Badari Pulavarty
Quoted 49 lines · Badari Pulavarty
Quoted 37 lines · Jens Axboe
Quoted 36 lines · Badari Pulavarty
Quoted 35 lines · Jens Axboe
Quoted 25 lines · Badari Pulavarty
Quoted 24 lines · Jens Axboe
Quoted 22 lines · Badari Pulavarty
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ???sym_scatter???:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ???for_each_sg??? drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ???;??? before ???{??? token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ???tp??? make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

drivers/scsi/qla2xxx/qla_iocb.c: In function ???qla24xx_build_scsi_iocbs???:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ???for_each_sg???
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ???;??? before ???{??? token

Quoted 3 lines
Quoted 1 line

Thanks, will fix those. What arch? I tested it here.

I am playing with them on ppc64.

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

git://git.kernel.dk/data/git/linux-2.6-block.git

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

I can mail you an updated patch, if you want.

Here is the whole panic stack..

Thanks will fix that up, the IDE part is totally untested. Can you try and backout this patch and see if it boots?

I increased max_segments to 1024 on my qla2200 attached disks and simple "dd" (direct read) resulted in following:

Quoted 6 lines

elm3b29:/sys/block/sdd/queue # echo 1024 > max_segments elm3b29:/sys/block/sdd/queue # cat max_hw_sectors_kb > max_sectors_kb elm3b29:/mnt # dd iflag=direct if=./z of=/dev/null bs=512M

Unable to handle kernel paging request at 0000000000001008 RIP:
 [<ffffffff8025e7af>] __rmqueue+0x6f/0x120

Auch, that's a bug. I don't think the oom path has been tested yet, perhaps this is hitting it.

Can you try with this debug patch, plus enable the slab debugging helpers (like poisoning)?

drivers/scsi/scsi_lib.c +1 -0
index 7456992..a479d1e 100644
@@ -793,6 +793,7 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 	return ret;
 enomem:
 	if (ret) {
+		printk(KERN_ERR "scsi: failed to allocate sg table\n");
 		/*
 		 * Free entries chained off ret. Since we were trying to
 		 * allocate another sglist, we know that all entries are of
Signature · 1 line
Jens Axboe
#11 lore raw
In reply to Jens Axboe
Quoted 21 lines · Jens Axboe
Quoted 20 lines · Badari Pulavarty

On Thu, 2007-05-17 at 08:27 +0200, Jens Axboe wrote:
..

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

git://git.kernel.dk/data/git/linux-2.6-block.git

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

I can mail you an updated patch, if you want.

Here is the whole panic stack..

Thanks will fix that up, the IDE part is totally untested. Can you try and backout this patch and see if it boots?

Yes. It boots fine with following backed out.

Looking at the code ide_probe.c: hwif_init() is doing

Quoted 9 lines
Quoted 5 lines
        hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
                                 GFP_KERNEL);

blk_rq_map_sg() is looking for the chaining info and going over end of the allocation.

Hmm, looks ok, I'm guessing it's just missing a memset (or just turn it into a kzalloc())?

Even with backing out all the ide changes, I get this on boot once in a while.

Thanks,
Badari

ReiserFS: hda2: checking transaction log (hda2)

Unable to handle kernel paging request at 00000000005e5e66 RIP:
 [<ffffffff80381aa1>] blk_rq_map_sg+0x71/0x1b0
PGD 0
Oops: 0000 [1] SMP
CPU 3
Modules linked in:
Pid: 1, comm: swapper Not tainted 2.6.22-rc1-sg #7
RIP: 0010:[<ffffffff80381aa1>]  [<ffffffff80381aa1>] blk_rq_map_sg
+0x71/0x1b0
RSP: 0000:ffff8101a024fcc8  EFLAGS: 00010287
RAX: 00000001df33e000 RBX: ffff8101df2b5f70 RCX: 000000019f352000
RDX: 0000000000000000 RSI: ffff8101df228300 RDI: 00000000001df33e
RBP: ffff8101a024fd28 R08: 00000000000004e2 R09: 0000000000000000
R10: 000000000000007f R11: 0000000000000001 R12: 00000000005e5e46
R13: 0000000000001000 R14: 0000000000000000 R15: ffff8101df2b5f60
FS:  0000000000000000(0000) GS:ffff8101c021f300(0000)

knlGS:0000000000000000
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 00000000005e5e66 CR3: 0000000000201000 CR4: 00000000000006e0 Process swapper (pid: 1, threadinfo ffff8101a0238000, task ffff810180238000)

Stack:  0000000300000000 ffff810179c58000 000000019f352000
ffff810179c562c0
 ffff8101df228e80 0000001700000082 01ff810100000001 ffff8101df3207a8
 ffffffff8078a500 ffff810179c56000 ffffffff8078a500 ffff8101df3207a8
Call Trace:
 <IRQ>  [<ffffffff8042faf2>] ide_map_sg+0x42/0xd0
 [<ffffffff8043936a>] ide_build_sglist+0x2a/0x90
 [<ffffffff804393ff>] ide_build_dmatable+0x2f/0x180
 [<ffffffff80439594>] ide_dma_setup+0x44/0xe0
 [<ffffffff8043cd99>] ide_do_rw_disk+0x349/0x510
 [<ffffffff80430442>] ide_do_request+0x622/0xb40
 [<ffffffff8042fd2d>] ide_end_request+0x9d/0x160
 [<ffffffff80439660>] ide_dma_intr+0x0/0xd0
 [<ffffffff80439660>] ide_dma_intr+0x0/0xd0
 [<ffffffff80430cdf>] ide_intr+0x23f/0x250
 [<ffffffff802571b5>] handle_IRQ_event+0x35/0x70
 [<ffffffff80258c8c>] handle_edge_irq+0xcc/0x150
 [<ffffffff8020caf0>] do_IRQ+0x80/0x100
 [<ffffffff8020a021>] ret_from_intr+0x0/0xa
 <EOI>  [<ffffffff802816c0>] kmem_cache_alloc+0x40/0x70
 [<ffffffff8025d001>] mempool_alloc_slab+0x11/0x20
 [<ffffffff8025d122>] mempool_alloc+0x42/0x110
 [<ffffffff80382db8>] generic_make_request+0x198/0x240
 [<ffffffff802aefee>] bio_alloc_bioset+0x2e/0x120
 [<ffffffff802af140>] bio_alloc+0x10/0x20
 [<ffffffff802ab11b>] submit_bh+0x6b/0x140
 [<ffffffff802ac180>] ll_rw_block+0xd0/0xe0
 [<ffffffff802ff1ae>] journal_read+0xb5e/0xec0
 [<ffffffff80265d71>] zone_statistics+0x61/0xa0
 [<ffffffff8025f528>] get_page_from_freelist+0x3c8/0x510
 [<ffffffff8025f7ae>] __alloc_pages+0x6e/0x330
 [<ffffffff80278aed>] alloc_page_interleave+0x8d/0xa0
 [<ffffffff80279c86>] alloc_pages_current+0x86/0x90
 [<ffffffff8025f140>] get_zeroed_page+0x20/0x40
 [<ffffffff80267704>] __pte_alloc_kernel+0x64/0x80
 [<ffffffff802721dc>] map_vm_area+0x1dc/0x2e0
 [<ffffffff80272907>] __vmalloc_area_node+0x157/0x1a0
 [<ffffffff80302169>] journal_init+0x819/0x990
 [<ffffffff80272907>] __vmalloc_area_node+0x157/0x1a0
 [<ffffffff802729bf>] __vmalloc_node+0x6f/0x80
 [<ffffffff802729fe>] __vmalloc+0xe/0x10
 [<ffffffff802f109a>] reiserfs_fill_super+0x2ba/0xc20
 [<ffffffff80394357>] vsnprintf+0x2e7/0x680
 [<ffffffff80394959>] snprintf+0x59/0x60
 [<ffffffff80505117>] __down_write_nested+0x17/0xc0
 [<ffffffff8039310f>] strlcpy+0x4f/0x70
 [<ffffffff80287ef0>] test_bdev_super+0x0/0x20
 [<ffffffff802892cc>] get_sb_bdev+0x13c/0x170
 [<ffffffff802f0de0>] reiserfs_fill_super+0x0/0xc20
 [<ffffffff802ee793>] get_super_block+0x13/0x20
 [<ffffffff80288b68>] vfs_kern_mount+0xd8/0x160
 [<ffffffff80288c5e>] do_kern_mount+0x4e/0x100
 [<ffffffff802a0852>] do_mount+0x4e2/0x790
 [<ffffffff8029a3ac>] __d_lookup+0x9c/0x130
 [<ffffffff8028ec24>] do_lookup+0x84/0x200
 [<ffffffff8028ec24>] do_lookup+0x84/0x200
 [<ffffffff802995c4>] dput+0x24/0x140
 [<ffffffff80290e49>] __link_path_walk+0x469/0xec0
 [<ffffffff80265d8d>] zone_statistics+0x7d/0xa0
 [<ffffffff8025f7ae>] __alloc_pages+0x6e/0x330
 [<ffffffff80278aed>] alloc_page_interleave+0x8d/0xa0
 [<ffffffff80279c86>] alloc_pages_current+0x86/0x90
 [<ffffffff8025f0fb>] __get_free_pages+0x1b/0x40
 [<ffffffff8029f0b2>] copy_mount_options+0x52/0x180
 [<ffffffff802a0b94>] sys_mount+0x94/0xf0
 [<ffffffff806aecf1>] do_mount_root+0x21/0xa0
 [<ffffffff806aef40>] mount_block_root+0x90/0x220
 [<ffffffff80292421>] sys_rmdir+0x11/0x20
 [<ffffffff806af1b6>] mount_root+0xe6/0xf0
 [<ffffffff806af26d>] prepare_namespace+0xad/0x160
 [<ffffffff806aeafa>] kernel_init+0x23a/0x330
 [<ffffffff8020a928>] child_rip+0xa/0x12
 [<ffffffff806ae8c0>] kernel_init+0x0/0x330
 [<ffffffff8020a91e>] child_rip+0x0/0x12


Code: 49 8b 44 24 20 49 8d 4c 24 20 48 89 c2 48 83 e2 fe a8 01 48
RIP  [<ffffffff80381aa1>] blk_rq_map_sg+0x71/0x1b0
 RSP <ffff8101a024fcc8>

CR2: 00000000005e5e66

author
#12 lore raw
Quoted 28 lines · Badari Pulavarty
Quoted 27 lines · Jens Axboe
Quoted 25 lines · Badari Pulavarty

On Thu, 2007-05-17 at 08:27 +0200, Jens Axboe wrote:
..

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

git://git.kernel.dk/data/git/linux-2.6-block.git

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

I can mail you an updated patch, if you want.

Here is the whole panic stack..

Thanks will fix that up, the IDE part is totally untested. Can you try and backout this patch and see if it boots?

Yes. It boots fine with following backed out.

Looking at the code ide_probe.c: hwif_init() is doing

        hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
                                 GFP_KERNEL);

blk_rq_map_sg() is looking for the chaining info and going over end of the allocation.

Quoted 6 lines
Quoted 3 lines

Hmm, looks ok, I'm guessing it's just missing a memset (or just turn it into a kzalloc())?

Even with backing out all the ide changes, I get this on boot once in a while.

Yep, I think the ide changes are fine as such, the problem is the missing memset/kzalloc. Can you try that?

Signature · 1 line
Jens Axboe
#13 lore raw
Quoted 33 lines · Jens Axboe
Quoted 32 lines · Badari Pulavarty
Quoted 30 lines · Jens Axboe
Quoted 18 lines · Badari Pulavarty

On Thu, 2007-05-17 at 08:27 +0200, Jens Axboe wrote:
..

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

git://git.kernel.dk/data/git/linux-2.6-block.git

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

I can mail you an updated patch, if you want.

Here is the whole panic stack..

Thanks will fix that up, the IDE part is totally untested. Can you try and backout this patch and see if it boots?

Yes. It boots fine with following backed out.

Quoted 7 lines

Looking at the code ide_probe.c: hwif_init() is doing

        hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
                                 GFP_KERNEL);

blk_rq_map_sg() is looking for the chaining info and going over end of the allocation.

Hmm, looks ok, I'm guessing it's just missing a memset (or just turn it into a kzalloc())?

Quoted 5 lines
Quoted 2 lines

Even with backing out all the ide changes, I get this on boot once in a while.

Yep, I think the ide changes are fine as such, the problem is the missing memset/kzalloc. Can you try that?

kzalloc() made it better. I haven't seen ide panics anymore. I will try it again after applying ide patches.

Thanks
Badari

#16 lore raw
In reply to Jens Axboe
Quoted 69 lines · Jens Axboe
Quoted 49 lines · Badari Pulavarty
Quoted 37 lines · Jens Axboe
Quoted 36 lines · Badari Pulavarty
Quoted 35 lines · Jens Axboe
Quoted 25 lines · Badari Pulavarty
Quoted 24 lines · Jens Axboe
Quoted 22 lines · Badari Pulavarty
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ???sym_scatter???:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ???for_each_sg??? drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ???;??? before ???{??? token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ???tp??? make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

drivers/scsi/qla2xxx/qla_iocb.c: In function ???qla24xx_build_scsi_iocbs???:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ???for_each_sg???
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ???;??? before ???{??? token

Quoted 3 lines
Quoted 1 line

Thanks, will fix those. What arch? I tested it here.

I am playing with them on ppc64.

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

git://git.kernel.dk/data/git/linux-2.6-block.git

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

I can mail you an updated patch, if you want.

Here is the whole panic stack..

Thanks will fix that up, the IDE part is totally untested. Can you try and backout this patch and see if it boots?

I increased max_segments to 1024 on my qla2200 attached disks and simple "dd" (direct read) resulted in following:

Quoted 6 lines

elm3b29:/sys/block/sdd/queue # echo 1024 > max_segments elm3b29:/sys/block/sdd/queue # cat max_hw_sectors_kb > max_sectors_kb elm3b29:/mnt # dd iflag=direct if=./z of=/dev/null bs=512M

Unable to handle kernel paging request at 0000000000001008 RIP:
 [<ffffffff8025e7af>] __rmqueue+0x6f/0x120

Auch, that's a bug. I don't think the oom path has been tested yet, perhaps this is hitting it.

Can you try with this debug patch, plus enable the slab debugging helpers (like poisoning)?

drivers/scsi/scsi_lib.c +0 -0
index 7456992..a479d1e 100644

drivers/scsi/scsi_lib.c struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) · line 799

Quoted 7 lines
drivers/scsi/scsi_lib.c +1 -0
@@ -793,6 +793,7 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 	return ret;
 enomem:
 	if (ret) {
+		printk(KERN_ERR "scsi: failed to allocate sg table\n");
 		/*
 		 * Free entries chained off ret. Since we were trying to
 		 * allocate another sglist, we know that all entries are of

Not much help. I get all kinds of weird panics.. This time I got (with the above debug).

general protection fault: 0000 [1] SMP
CPU 1
Modules linked in: jfs sg sd_mod qla2xxx firmware_class
scsi_transport_fc scsi_mod vfat fat ipv6 thermal processor fan button
battery ac dm_mod floppy parport_pc lp parport
Pid: 56, comm: kblockd/1 Not tainted 2.6.22-rc1-sg #8
RIP: 0010:[<ffffffff802816b6>]  [<ffffffff802816b6>] kmem_cache_alloc
+0x36/0x70
RSP: 0018:ffff81017abbfc10  EFLAGS: 00010002
RAX: 0000000000000000 RBX: 0000000000000082 RCX: 0600000000000064
RDX: ffff81019ff2b8a0 RSI: 0000000000011220 RDI: ffffffff8068d120
RBP: ffff81017abbfc20 R08: 00000000000039f8 R09: 0000000000000000
R10: ffff81019cbee700 R11: 0000000000000188 R12: ffff8101df2a64e0
R13: 0000000000011220 R14: ffff8101df2a6510 R15: ffff81017abbfc50
FS:  00002b505b027f20(0000) GS:ffff81018021f300(0000)

knlGS:00000000f7da26b0
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 00002b505b029008 CR3: 000000019af73000 CR4: 00000000000006e0 Process kblockd/1 (pid: 56, threadinfo ffff81017abbe000, task ffff81017a571440)

Stack:  000000007abbfc30 0000000000000000 ffff81017abbfc30
ffffffff8025d001
 ffff81017abbfcb0 ffffffff8025d122 ffff81017abbfc60 ffffffff80219dc0
 ffffffff880e5da6 00000000000000ad ffff81017abbfcd0 ffffffff8021a366
Call Trace:
 [<ffffffff8025d001>] mempool_alloc_slab+0x11/0x20
 [<ffffffff8025d122>] mempool_alloc+0x42/0x110
 [<ffffffff80219dc0>] flush_gart+0x40/0x50
 [<ffffffff880e5da6>] :scsi_mod:__scsi_get_command+0x26/0x90
 [<ffffffff8021a366>] gart_map_sg+0x2d6/0x3e0
 [<ffffffff880ebb70>] :scsi_mod:scsi_alloc_sgtable+0x90/0x1e0
 [<ffffffff880ebcf7>] :scsi_mod:scsi_init_io+0x37/0x120
 [<ffffffff880ebe7d>] :scsi_mod:scsi_prep_fn+0x9d/0x300
 [<ffffffff80380772>] elv_next_request+0xa2/0x180
 [<ffffffff8038fc2a>] kobject_get+0x1a/0x30
 [<ffffffff880ecd78>] :scsi_mod:scsi_request_fn+0x218/0x3d0
 [<ffffffff80381310>] blk_unplug_work+0x0/0x20
 [<ffffffff80384155>] __generic_unplug_device+0x25/0x30
 [<ffffffff80385210>] generic_unplug_device+0x20/0x40
 [<ffffffff80381321>] blk_unplug_work+0x11/0x20
 [<ffffffff80241059>] run_workqueue+0x89/0x120
 [<ffffffff80241785>] worker_thread+0xd5/0x190
 [<ffffffff80244fc0>] autoremove_wake_function+0x0/0x40
 [<ffffffff802416b0>] worker_thread+0x0/0x190
 [<ffffffff80244bbd>] kthread+0x4d/0x80
 [<ffffffff8020a928>] child_rip+0xa/0x12
 [<ffffffff80244b70>] kthread+0x0/0x80
 [<ffffffff8020a91e>] child_rip+0x0/0x12


Code: 48 8b 04 c1 48 89 42 10 53 9d 48 83 c4 08 48 89 c8 5b c9 c3
RIP  [<ffffffff802816b6>] kmem_cache_alloc+0x36/0x70
 RSP <ffff81017abbfc10>
author
#17 lore raw
Quoted 101 lines · Badari Pulavarty
Quoted 69 lines · Jens Axboe
Quoted 49 lines · Badari Pulavarty
Quoted 37 lines · Jens Axboe
Quoted 36 lines · Badari Pulavarty
Quoted 35 lines · Jens Axboe
Quoted 25 lines · Badari Pulavarty
Quoted 24 lines · Jens Axboe
Quoted 22 lines · Badari Pulavarty
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ???sym_scatter???:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ???for_each_sg??? drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ???;??? before ???{??? token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ???tp??? make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

drivers/scsi/qla2xxx/qla_iocb.c: In function ???qla24xx_build_scsi_iocbs???:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ???for_each_sg???
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ???;??? before ???{??? token

Quoted 3 lines
Quoted 1 line

Thanks, will fix those. What arch? I tested it here.

I am playing with them on ppc64.

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

git://git.kernel.dk/data/git/linux-2.6-block.git

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

I can mail you an updated patch, if you want.

Here is the whole panic stack..

Thanks will fix that up, the IDE part is totally untested. Can you try and backout this patch and see if it boots?

I increased max_segments to 1024 on my qla2200 attached disks and simple "dd" (direct read) resulted in following:

Quoted 6 lines

elm3b29:/sys/block/sdd/queue # echo 1024 > max_segments elm3b29:/sys/block/sdd/queue # cat max_hw_sectors_kb > max_sectors_kb elm3b29:/mnt # dd iflag=direct if=./z of=/dev/null bs=512M

Unable to handle kernel paging request at 0000000000001008 RIP:
 [<ffffffff8025e7af>] __rmqueue+0x6f/0x120

Auch, that's a bug. I don't think the oom path has been tested yet, perhaps this is hitting it.

Can you try with this debug patch, plus enable the slab debugging helpers (like poisoning)?

drivers/scsi/scsi_lib.c +0 -0
index 7456992..a479d1e 100644

drivers/scsi/scsi_lib.c struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) · line 799

Quoted 7 lines
drivers/scsi/scsi_lib.c +1 -0
@@ -793,6 +793,7 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 	return ret;
 enomem:
 	if (ret) {
+		printk(KERN_ERR "scsi: failed to allocate sg table\n");
 		/*
 		 * Free entries chained off ret. Since we were trying to
 		 * allocate another sglist, we know that all entries are of

Not much help. I get all kinds of weird panics.. This time I got (with the above debug).

general protection fault: 0000 [1] SMP
CPU 1
Modules linked in: jfs sg sd_mod qla2xxx firmware_class
scsi_transport_fc scsi_mod vfat fat ipv6 thermal processor fan button
battery ac dm_mod floppy parport_pc lp parport
Pid: 56, comm: kblockd/1 Not tainted 2.6.22-rc1-sg #8
RIP: 0010:[<ffffffff802816b6>]  [<ffffffff802816b6>] kmem_cache_alloc
+0x36/0x70
RSP: 0018:ffff81017abbfc10  EFLAGS: 00010002
RAX: 0000000000000000 RBX: 0000000000000082 RCX: 0600000000000064
RDX: ffff81019ff2b8a0 RSI: 0000000000011220 RDI: ffffffff8068d120
RBP: ffff81017abbfc20 R08: 00000000000039f8 R09: 0000000000000000
R10: ffff81019cbee700 R11: 0000000000000188 R12: ffff8101df2a64e0
R13: 0000000000011220 R14: ffff8101df2a6510 R15: ffff81017abbfc50
FS:  00002b505b027f20(0000) GS:ffff81018021f300(0000)

knlGS:00000000f7da26b0
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 00002b505b029008 CR3: 000000019af73000 CR4: 00000000000006e0 Process kblockd/1 (pid: 56, threadinfo ffff81017abbe000, task ffff81017a571440)

Quoted 10 lines
Stack:  000000007abbfc30 0000000000000000 ffff81017abbfc30
ffffffff8025d001
 ffff81017abbfcb0 ffffffff8025d122 ffff81017abbfc60 ffffffff80219dc0
 ffffffff880e5da6 00000000000000ad ffff81017abbfcd0 ffffffff8021a366
Call Trace:
 [<ffffffff8025d001>] mempool_alloc_slab+0x11/0x20
 [<ffffffff8025d122>] mempool_alloc+0x42/0x110
 [<ffffffff80219dc0>] flush_gart+0x40/0x50
 [<ffffffff880e5da6>] :scsi_mod:__scsi_get_command+0x26/0x90
 [<ffffffff8021a366>] gart_map_sg+0x2d6/0x3e0

Smells like a bug in the gart modifications, I'll double check them. Does it work if you boot with iommu=off?

Signature · 1 line
Jens Axboe
author
#18 lore raw
Quoted 113 lines · Jens Axboe
Quoted 101 lines · Badari Pulavarty
Quoted 69 lines · Jens Axboe
Quoted 49 lines · Badari Pulavarty
Quoted 37 lines · Jens Axboe
Quoted 36 lines · Badari Pulavarty
Quoted 35 lines · Jens Axboe
Quoted 25 lines · Badari Pulavarty
Quoted 24 lines · Jens Axboe
Quoted 22 lines · Badari Pulavarty
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ???sym_scatter???:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ???for_each_sg??? drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ???;??? before ???{??? token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ???tp??? make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

drivers/scsi/qla2xxx/qla_iocb.c: In function ???qla24xx_build_scsi_iocbs???:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ???for_each_sg???
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ???;??? before ???{??? token

Quoted 3 lines
Quoted 1 line

Thanks, will fix those. What arch? I tested it here.

I am playing with them on ppc64.

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

git://git.kernel.dk/data/git/linux-2.6-block.git

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

I can mail you an updated patch, if you want.

Here is the whole panic stack..

Thanks will fix that up, the IDE part is totally untested. Can you try and backout this patch and see if it boots?

I increased max_segments to 1024 on my qla2200 attached disks and simple "dd" (direct read) resulted in following:

Quoted 6 lines

elm3b29:/sys/block/sdd/queue # echo 1024 > max_segments elm3b29:/sys/block/sdd/queue # cat max_hw_sectors_kb > max_sectors_kb elm3b29:/mnt # dd iflag=direct if=./z of=/dev/null bs=512M

Unable to handle kernel paging request at 0000000000001008 RIP:
 [<ffffffff8025e7af>] __rmqueue+0x6f/0x120

Auch, that's a bug. I don't think the oom path has been tested yet, perhaps this is hitting it.

Can you try with this debug patch, plus enable the slab debugging helpers (like poisoning)?

drivers/scsi/scsi_lib.c +0 -0
index 7456992..a479d1e 100644

drivers/scsi/scsi_lib.c struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) · line 799

Quoted 7 lines
drivers/scsi/scsi_lib.c +1 -0
@@ -793,6 +793,7 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 	return ret;
 enomem:
 	if (ret) {
+		printk(KERN_ERR "scsi: failed to allocate sg table\n");
 		/*
 		 * Free entries chained off ret. Since we were trying to
 		 * allocate another sglist, we know that all entries are of

Not much help. I get all kinds of weird panics.. This time I got (with the above debug).

general protection fault: 0000 [1] SMP
CPU 1
Modules linked in: jfs sg sd_mod qla2xxx firmware_class
scsi_transport_fc scsi_mod vfat fat ipv6 thermal processor fan button
battery ac dm_mod floppy parport_pc lp parport
Pid: 56, comm: kblockd/1 Not tainted 2.6.22-rc1-sg #8
RIP: 0010:[<ffffffff802816b6>]  [<ffffffff802816b6>] kmem_cache_alloc
+0x36/0x70
RSP: 0018:ffff81017abbfc10  EFLAGS: 00010002
RAX: 0000000000000000 RBX: 0000000000000082 RCX: 0600000000000064
RDX: ffff81019ff2b8a0 RSI: 0000000000011220 RDI: ffffffff8068d120
RBP: ffff81017abbfc20 R08: 00000000000039f8 R09: 0000000000000000
R10: ffff81019cbee700 R11: 0000000000000188 R12: ffff8101df2a64e0
R13: 0000000000011220 R14: ffff8101df2a6510 R15: ffff81017abbfc50
FS:  00002b505b027f20(0000) GS:ffff81018021f300(0000)

knlGS:00000000f7da26b0
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 00002b505b029008 CR3: 000000019af73000 CR4: 00000000000006e0 Process kblockd/1 (pid: 56, threadinfo ffff81017abbe000, task ffff81017a571440)

Quoted 10 lines
Stack:  000000007abbfc30 0000000000000000 ffff81017abbfc30
ffffffff8025d001
 ffff81017abbfcb0 ffffffff8025d122 ffff81017abbfc60 ffffffff80219dc0
 ffffffff880e5da6 00000000000000ad ffff81017abbfcd0 ffffffff8021a366
Call Trace:
 [<ffffffff8025d001>] mempool_alloc_slab+0x11/0x20
 [<ffffffff8025d122>] mempool_alloc+0x42/0x110
 [<ffffffff80219dc0>] flush_gart+0x40/0x50
 [<ffffffff880e5da6>] :scsi_mod:__scsi_get_command+0x26/0x90
 [<ffffffff8021a366>] gart_map_sg+0x2d6/0x3e0
Quoted 2 lines

Smells like a bug in the gart modifications, I'll double check them. Does it work if you boot with iommu=off?

If iommu=off works, can you try a normal boot but with this applied on top of the sglist patches? That should fix gart mapping.

arch/x86_64/kernel/pci-gart.c +6 -5
index 2e22a3a..b16384f 100644
@@ -381,7 +381,7 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
 	int start;
 	unsigned long pages = 0;
 	int need = 0, nextneed;
-	struct scatterlist *s, *ps, *start_sg;
+	struct scatterlist *s, *ps, *start_sg, *sgmap;
 
 	if (nents == 0) 
 		return 0;
@@ -391,7 +391,7 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
 
 	out = 0;
 	start = 0;
-	start_sg = sg;
+	start_sg = sgmap = sg;
 	ps = NULL; /* shut up gcc */
 	for_each_sg(sg, s, nents, i) {
 		dma_addr_t addr = page_to_phys(s->page) + s->offset;
@@ -405,11 +405,12 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
 			/* Can only merge when the last chunk ends on a page 
 			   boundary and the new one doesn't have an offset. */
 			if (!iommu_merge || !nextneed || !need || s->offset ||
-			    (ps->offset + ps->length) % PAGE_SIZE) { 
-				if (dma_map_cont(start_sg, i - start, sg+out,
+			    (ps->offset + ps->length) % PAGE_SIZE) {
+				if (dma_map_cont(start_sg, i - start, sgmap,
 						  pages, need) < 0)
 					goto error;
 				out++;
+				sgmap = sg_next(sgmap);
 				pages = 0;
 				start = i;
 				start_sg = s;
@@ -420,7 +421,7 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
 		pages += to_pages(s->offset, s->length);
 		ps = s;
 	}
-	if (dma_map_cont(start_sg, i - start, sg+out, pages, need) < 0)
+	if (dma_map_cont(start_sg, i - start, sgmap, pages, need) < 0)
 		goto error;
 	out++;
 	flush_gart();
Signature · 1 line
Jens Axboe
#19 lore raw
Quoted 149 lines · Jens Axboe
Quoted 103 lines · Jens Axboe
Quoted 92 lines · Badari Pulavarty
Quoted 61 lines · Jens Axboe
Quoted 42 lines · Badari Pulavarty
Quoted 31 lines · Jens Axboe
Quoted 30 lines · Badari Pulavarty
Quoted 29 lines · Jens Axboe
Quoted 18 lines · Badari Pulavarty
Quoted 17 lines · Jens Axboe
Quoted 16 lines · Badari Pulavarty
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ???sym_scatter???:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ???for_each_sg??? drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ???;??? before ???{??? token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ???tp??? make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

Quoted 7 lines
Quoted 6 lines
Quoted 5 lines

drivers/scsi/qla2xxx/qla_iocb.c: In function ???qla24xx_build_scsi_iocbs???:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ???for_each_sg???
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ???;??? before ???{??? token

Thanks, will fix those. What arch? I tested it here.

I am playing with them on ppc64.

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines

git://git.kernel.dk/data/git/linux-2.6-block.git

I can mail you an updated patch, if you want.

Here is the whole panic stack..

Thanks will fix that up, the IDE part is totally untested. Can you try and backout this patch and see if it boots?

I increased max_segments to 1024 on my qla2200 attached disks and simple "dd" (direct read) resulted in following:

Quoted 6 lines

elm3b29:/sys/block/sdd/queue # echo 1024 > max_segments elm3b29:/sys/block/sdd/queue # cat max_hw_sectors_kb > max_sectors_kb elm3b29:/mnt # dd iflag=direct if=./z of=/dev/null bs=512M

Unable to handle kernel paging request at 0000000000001008 RIP:
 [<ffffffff8025e7af>] __rmqueue+0x6f/0x120

Auch, that's a bug. I don't think the oom path has been tested yet, perhaps this is hitting it.

Can you try with this debug patch, plus enable the slab debugging helpers (like poisoning)?

drivers/scsi/scsi_lib.c +0 -0
index 7456992..a479d1e 100644

drivers/scsi/scsi_lib.c struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) · line 799

Quoted 7 lines
drivers/scsi/scsi_lib.c +1 -0
@@ -793,6 +793,7 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 	return ret;
 enomem:
 	if (ret) {
+		printk(KERN_ERR "scsi: failed to allocate sg table\n");
 		/*
 		 * Free entries chained off ret. Since we were trying to
 		 * allocate another sglist, we know that all entries are of

Not much help. I get all kinds of weird panics.. This time I got (with the above debug).

general protection fault: 0000 [1] SMP
CPU 1
Modules linked in: jfs sg sd_mod qla2xxx firmware_class
scsi_transport_fc scsi_mod vfat fat ipv6 thermal processor fan button
battery ac dm_mod floppy parport_pc lp parport
Pid: 56, comm: kblockd/1 Not tainted 2.6.22-rc1-sg #8
RIP: 0010:[<ffffffff802816b6>]  [<ffffffff802816b6>] kmem_cache_alloc
+0x36/0x70
RSP: 0018:ffff81017abbfc10  EFLAGS: 00010002
RAX: 0000000000000000 RBX: 0000000000000082 RCX: 0600000000000064
RDX: ffff81019ff2b8a0 RSI: 0000000000011220 RDI: ffffffff8068d120
RBP: ffff81017abbfc20 R08: 00000000000039f8 R09: 0000000000000000
R10: ffff81019cbee700 R11: 0000000000000188 R12: ffff8101df2a64e0
R13: 0000000000011220 R14: ffff8101df2a6510 R15: ffff81017abbfc50
FS:  00002b505b027f20(0000) GS:ffff81018021f300(0000)

knlGS:00000000f7da26b0
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 00002b505b029008 CR3: 000000019af73000 CR4: 00000000000006e0 Process kblockd/1 (pid: 56, threadinfo ffff81017abbe000, task ffff81017a571440)

Quoted 10 lines
Stack:  000000007abbfc30 0000000000000000 ffff81017abbfc30
ffffffff8025d001
 ffff81017abbfcb0 ffffffff8025d122 ffff81017abbfc60 ffffffff80219dc0
 ffffffff880e5da6 00000000000000ad ffff81017abbfcd0 ffffffff8021a366
Call Trace:
 [<ffffffff8025d001>] mempool_alloc_slab+0x11/0x20
 [<ffffffff8025d122>] mempool_alloc+0x42/0x110
 [<ffffffff80219dc0>] flush_gart+0x40/0x50
 [<ffffffff880e5da6>] :scsi_mod:__scsi_get_command+0x26/0x90
 [<ffffffff8021a366>] gart_map_sg+0x2d6/0x3e0
Quoted 2 lines

Smells like a bug in the gart modifications, I'll double check them. Does it work if you boot with iommu=off?

If iommu=off works, can you try a normal boot but with this applied on top of the sglist patches? That should fix gart mapping.

arch/x86_64/kernel/pci-gart.c +5 -4
index 2e22a3a..b16384f 100644
@@ -381,7 +381,7 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
 	int start;
 	unsigned long pages = 0;
 	int need = 0, nextneed;
-	struct scatterlist *s, *ps, *start_sg;
+	struct scatterlist *s, *ps, *start_sg, *sgmap;
 
 	if (nents == 0) 
 		return 0;
@@ -391,7 +391,7 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
 
 	out = 0;
 	start = 0;
-	start_sg = sg;
+	start_sg = sgmap = sg;
 	ps = NULL; /* shut up gcc */
 	for_each_sg(sg, s, nents, i) {
 		dma_addr_t addr = page_to_phys(s->page) + s->offset;
@@ -405,11 +405,12 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
 			/* Can only merge when the last chunk ends on a page 
 			   boundary and the new one doesn't have an offset. */
 			if (!iommu_merge || !nextneed || !need || s->offset ||
-			    (ps->offset + ps->length) % PAGE_SIZE) { 
-				if (dma_map_cont(start_sg, i - start, sg+out,
+			    (ps->offset + ps->length) % PAGE_SIZE) {
+				if (dma_map_cont(start_sg, i - start, sgmap,
 						  pages, need) < 0)
 					goto error;
 				out++;
+				sgmap = sg_next(sgmap);
 				pages = 0;
 				start = i;
 				start_sg = s;

arch/x86_64/kernel/pci-gart.c int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) · line 427

Quoted 8 lines
arch/x86_64/kernel/pci-gart.c +1 -1
@@ -420,7 +421,7 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
 		pages += to_pages(s->offset, s->length);
 		ps = s;
 	}
-	if (dma_map_cont(start_sg, i - start, sg+out, pages, need) < 0)
+	if (dma_map_cont(start_sg, i - start, sgmap, pages, need) < 0)
 		goto error;
 	out++;
 	flush_gart();

Looks good.
Thanks for picking this up.

Benny

#33 lore raw
In reply to Jens Axboe
Quoted 113 lines · Jens Axboe
Quoted 101 lines · Badari Pulavarty
Quoted 69 lines · Jens Axboe
Quoted 49 lines · Badari Pulavarty
Quoted 37 lines · Jens Axboe
Quoted 36 lines · Badari Pulavarty
Quoted 35 lines · Jens Axboe
Quoted 25 lines · Badari Pulavarty
Quoted 24 lines · Jens Axboe
Quoted 22 lines · Badari Pulavarty
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ???sym_scatter???:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ???for_each_sg??? drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ???;??? before ???{??? token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ???tp??? make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

drivers/scsi/qla2xxx/qla_iocb.c: In function ???qla24xx_build_scsi_iocbs???:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ???for_each_sg???
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ???;??? before ???{??? token

Quoted 3 lines
Quoted 1 line

Thanks, will fix those. What arch? I tested it here.

I am playing with them on ppc64.

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

git://git.kernel.dk/data/git/linux-2.6-block.git

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

I can mail you an updated patch, if you want.

Here is the whole panic stack..

Thanks will fix that up, the IDE part is totally untested. Can you try and backout this patch and see if it boots?

I increased max_segments to 1024 on my qla2200 attached disks and simple "dd" (direct read) resulted in following:

Quoted 6 lines

elm3b29:/sys/block/sdd/queue # echo 1024 > max_segments elm3b29:/sys/block/sdd/queue # cat max_hw_sectors_kb > max_sectors_kb elm3b29:/mnt # dd iflag=direct if=./z of=/dev/null bs=512M

Unable to handle kernel paging request at 0000000000001008 RIP:
 [<ffffffff8025e7af>] __rmqueue+0x6f/0x120

Auch, that's a bug. I don't think the oom path has been tested yet, perhaps this is hitting it.

Can you try with this debug patch, plus enable the slab debugging helpers (like poisoning)?

drivers/scsi/scsi_lib.c +0 -0
index 7456992..a479d1e 100644

drivers/scsi/scsi_lib.c struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) · line 799

Quoted 7 lines
drivers/scsi/scsi_lib.c +1 -0
@@ -793,6 +793,7 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 	return ret;
 enomem:
 	if (ret) {
+		printk(KERN_ERR "scsi: failed to allocate sg table\n");
 		/*
 		 * Free entries chained off ret. Since we were trying to
 		 * allocate another sglist, we know that all entries are of

Not much help. I get all kinds of weird panics.. This time I got (with the above debug).

general protection fault: 0000 [1] SMP
CPU 1
Modules linked in: jfs sg sd_mod qla2xxx firmware_class
scsi_transport_fc scsi_mod vfat fat ipv6 thermal processor fan button
battery ac dm_mod floppy parport_pc lp parport
Pid: 56, comm: kblockd/1 Not tainted 2.6.22-rc1-sg #8
RIP: 0010:[<ffffffff802816b6>]  [<ffffffff802816b6>] kmem_cache_alloc
+0x36/0x70
RSP: 0018:ffff81017abbfc10  EFLAGS: 00010002
RAX: 0000000000000000 RBX: 0000000000000082 RCX: 0600000000000064
RDX: ffff81019ff2b8a0 RSI: 0000000000011220 RDI: ffffffff8068d120
RBP: ffff81017abbfc20 R08: 00000000000039f8 R09: 0000000000000000
R10: ffff81019cbee700 R11: 0000000000000188 R12: ffff8101df2a64e0
R13: 0000000000011220 R14: ffff8101df2a6510 R15: ffff81017abbfc50
FS:  00002b505b027f20(0000) GS:ffff81018021f300(0000)

knlGS:00000000f7da26b0
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 00002b505b029008 CR3: 000000019af73000 CR4: 00000000000006e0 Process kblockd/1 (pid: 56, threadinfo ffff81017abbe000, task ffff81017a571440)

Quoted 10 lines
Stack:  000000007abbfc30 0000000000000000 ffff81017abbfc30
ffffffff8025d001
 ffff81017abbfcb0 ffffffff8025d122 ffff81017abbfc60 ffffffff80219dc0
 ffffffff880e5da6 00000000000000ad ffff81017abbfcd0 ffffffff8021a366
Call Trace:
 [<ffffffff8025d001>] mempool_alloc_slab+0x11/0x20
 [<ffffffff8025d122>] mempool_alloc+0x42/0x110
 [<ffffffff80219dc0>] flush_gart+0x40/0x50
 [<ffffffff880e5da6>] :scsi_mod:__scsi_get_command+0x26/0x90
 [<ffffffff8021a366>] gart_map_sg+0x2d6/0x3e0
Quoted 3 lines

Smells like a bug in the gart modifications, I'll double check them. Does it work if you boot with iommu=off?

Sorry for not getting back earlier. iommu=off on my machine generates tons & tons of following messages and makes machine almost unusable..

nommu_map_sg: overflow 1da18f000+4096 of device mask ffffffff
nommu_map_sg: overflow 1d5322000+4096 of device mask ffffffff
nommu_map_sg: overflow 1d306f000+4096 of device mask ffffffff
nommu_map_sg: overflow 1dc233000+4096 of device mask ffffffff
nommu_map_sg: overflow 1d9d53000+4096 of device mask ffffffff
nommu_map_sg: overflow 1d5322000+4096 of device mask ffffffff
nommu_map_sg: overflow 1d306f000+4096 of device mask ffffffff
nommu_map_sg: overflow 1da189000+4096 of device mask ffffffff
nommu_map_sg: overflow 1d9d97000+4096 of device mask ffffffff
nommu_map_sg: overflow 1d5322000+4096 of device mask ffffffff
nommu_map_sg: overflow 1d306f000+4096 of device mask ffffffff

I will apply the suggested patch and re-run the test.

Thanks,
Badari

#20 lore raw
In reply to Jens Axboe

arch/x86_64/kernel/pci-gart.c

Quoted 124 lines · Jens Axboe
Quoted 113 lines · Jens Axboe
Quoted 101 lines · Badari Pulavarty
Quoted 69 lines · Jens Axboe
Quoted 49 lines · Badari Pulavarty
Quoted 37 lines · Jens Axboe
Quoted 36 lines · Badari Pulavarty
Quoted 35 lines · Jens Axboe
Quoted 25 lines · Badari Pulavarty
Quoted 24 lines · Jens Axboe
Quoted 22 lines · Badari Pulavarty
Quoted 4 lines · Jens Axboe

Hi,

Updated version of the patch - this time I'll just attach the patch file...

Missing scatterlist.h inclusions..

drivers/scsi/sym53c8xx_2/sym_glue.c: In function ???sym_scatter???:
drivers/scsi/sym53c8xx_2/sym_glue.c:385: warning: implicit declaration of function ???for_each_sg??? drivers/scsi/sym53c8xx_2/sym_glue.c:385: error: expected ???;??? before ???{??? token
drivers/scsi/sym53c8xx_2/sym_glue.c:375: warning: unused variable ???tp??? make[3]: *** [drivers/scsi/sym53c8xx_2/sym_glue.o] Error 1

drivers/scsi/qla2xxx/qla_iocb.c: In function ???qla24xx_build_scsi_iocbs???:
drivers/scsi/qla2xxx/qla_iocb.c:678: warning: implicit declaration of function ???for_each_sg???
drivers/scsi/qla2xxx/qla_iocb.c:678: error: expected ???;??? before ???{??? token

Quoted 3 lines
Quoted 1 line

Thanks, will fix those. What arch? I tested it here.

I am playing with them on ppc64.

Ah ok, you need the updated patch series for ppc64 support. Builds fine here on ppc64. See the #sglist branch of the block repo:

git://git.kernel.dk/data/git/linux-2.6-block.git

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

I can mail you an updated patch, if you want.

Here is the whole panic stack..

Thanks will fix that up, the IDE part is totally untested. Can you try and backout this patch and see if it boots?

I increased max_segments to 1024 on my qla2200 attached disks and simple "dd" (direct read) resulted in following:

Quoted 6 lines

elm3b29:/sys/block/sdd/queue # echo 1024 > max_segments elm3b29:/sys/block/sdd/queue # cat max_hw_sectors_kb > max_sectors_kb elm3b29:/mnt # dd iflag=direct if=./z of=/dev/null bs=512M

Unable to handle kernel paging request at 0000000000001008 RIP:
 [<ffffffff8025e7af>] __rmqueue+0x6f/0x120

Auch, that's a bug. I don't think the oom path has been tested yet, perhaps this is hitting it.

Can you try with this debug patch, plus enable the slab debugging helpers (like poisoning)?

drivers/scsi/scsi_lib.c +0 -0
index 7456992..a479d1e 100644

drivers/scsi/scsi_lib.c struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) · line 799

Quoted 7 lines
drivers/scsi/scsi_lib.c +1 -0
@@ -793,6 +793,7 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 	return ret;
 enomem:
 	if (ret) {
+		printk(KERN_ERR "scsi: failed to allocate sg table\n");
 		/*
 		 * Free entries chained off ret. Since we were trying to
 		 * allocate another sglist, we know that all entries are of

Not much help. I get all kinds of weird panics.. This time I got (with the above debug).

general protection fault: 0000 [1] SMP
CPU 1
Modules linked in: jfs sg sd_mod qla2xxx firmware_class
scsi_transport_fc scsi_mod vfat fat ipv6 thermal processor fan button
battery ac dm_mod floppy parport_pc lp parport
Pid: 56, comm: kblockd/1 Not tainted 2.6.22-rc1-sg #8
RIP: 0010:[<ffffffff802816b6>]  [<ffffffff802816b6>] kmem_cache_alloc
+0x36/0x70
RSP: 0018:ffff81017abbfc10  EFLAGS: 00010002
RAX: 0000000000000000 RBX: 0000000000000082 RCX: 0600000000000064
RDX: ffff81019ff2b8a0 RSI: 0000000000011220 RDI: ffffffff8068d120
RBP: ffff81017abbfc20 R08: 00000000000039f8 R09: 0000000000000000
R10: ffff81019cbee700 R11: 0000000000000188 R12: ffff8101df2a64e0
R13: 0000000000011220 R14: ffff8101df2a6510 R15: ffff81017abbfc50
FS:  00002b505b027f20(0000) GS:ffff81018021f300(0000)

knlGS:00000000f7da26b0
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 00002b505b029008 CR3: 000000019af73000 CR4: 00000000000006e0 Process kblockd/1 (pid: 56, threadinfo ffff81017abbe000, task ffff81017a571440)

Quoted 10 lines
Stack:  000000007abbfc30 0000000000000000 ffff81017abbfc30
ffffffff8025d001
 ffff81017abbfcb0 ffffffff8025d122 ffff81017abbfc60 ffffffff80219dc0
 ffffffff880e5da6 00000000000000ad ffff81017abbfcd0 ffffffff8021a366
Call Trace:
 [<ffffffff8025d001>] mempool_alloc_slab+0x11/0x20
 [<ffffffff8025d122>] mempool_alloc+0x42/0x110
 [<ffffffff80219dc0>] flush_gart+0x40/0x50
 [<ffffffff880e5da6>] :scsi_mod:__scsi_get_command+0x26/0x90
 [<ffffffff8021a366>] gart_map_sg+0x2d6/0x3e0
Quoted 2 lines

Smells like a bug in the gart modifications, I'll double check them. Does it work if you boot with iommu=off?

If iommu=off works, can you try a normal boot but with this applied on top of the sglist patches? That should fix gart mapping.

arch/x86_64/kernel/pci-gart.c +0 -0
index 2e22a3a..b16384f 100644

Yes. With this patch + kzalloc() for ide probe took care of all my problems on x86-64.

But my ppc64 box is still sick :(

Thanks,
Badari

Oops: Kernel access of bad area, sig: 11 [#1]
SMP NR_CPUS=32 NUMA pSeries
Modules linked in: qla2xxx scsi_transport_fc
NIP: c0000000000414a0 LR: c00000000004162c CTR: 0000000000000001
REGS: c0000000047bb130 TRAP: 0300   Not tainted  (2.6.22-rc1)
MSR: 8000000000001032 <ME,IR,DR>  CR: 28000022  XER: 00000008
DAR: 0000000000000000, DSISR: 0000000040000000

TASK = c0000000047a6aa0[0] 'swapper' THREAD: c0000000047b8000 CPU: 7
GPR00: 0000000000000080 c0000000047bb3b0 c000000000692358 c0000000047a6aa0
GPR04: 0000000000000000 0000000000000070 0000000000000000 c0000000005ac0b8
GPR08: 000000000000e4b4 0000000000000001 0000000000000000 0000000000000280
GPR12: 0000000000000020 c0000000005a3e80 0000000000000000 0000000007a8dd70
GPR16: 0000000000000000 0000000000000000 0000000000000000 c0000000047b8000
GPR20: 000000003b9aca00 c0000000047a6c50 0000000000000001 0000000000000000
GPR24: d000000000909048 0001dee6d30c0d30 c000000003b7dd80 c0000000047a6aa0
GPR28: 00000001079027ca c0000000047a6aa0 c0000000005b7cb0 c000000000472c9c NIP [c0000000000414a0] .dequeue_task+0x0/0x9c
LR [c00000000004162c] .deactivate_task+0x40/0x60

Call Trace:
[c0000000047bb3b0] [c00000000004bccc] .printk+0x38/0x48 (unreliable)
[c0000000047bb440] [c000000000471704] .schedule+0x1fc/0x8dc
[c0000000047bb540] [c000000000472c9c] .schedule_timeout+0xa8/0xe8
[c0000000047bb610] [c000000000057260] .msleep+0x20/0x38
[c0000000047bb690] [c00000000003f5ec] .eeh_dn_check_failure+0x114/0x268
[c0000000047bb740] [c00000000003fc64] .eeh_check_failure+0xec/0x114
[c0000000047bb7c0] [d00000000086190c] .qla2300_fw_dump+0x1130/0x1c00 [qla2xxx]
[c0000000047bb8a0] [d000000000858d50] .qla2300_intr_handler+0x1e8/0x60c [qla2xxx]
[c0000000047bb950] [c000000000078368] .handle_IRQ_event+0x70/0xe4
[c0000000047bb9f0] [c00000000007a7e0] .handle_fasteoi_irq+0x11c/0x1d0
[c0000000047bba90] [c00000000000c178] .do_IRQ+0x90/0xec
[c0000000047bbb10] [c000000000004790] hardware_interrupt_entry+0x18/0x1c
--- Exception: 501 at .ppc64_runlatch_off+0x20/0x50
    LR = .pseries_dedicated_idle_sleep+0x88/0x11c

[c0000000047bbe00] [c0000000047bbe80] 0xc0000000047bbe80 (unreliable) [c0000000047bbe80] [c0000000000108f4] .cpu_idle+0xc8/0x118 [c0000000047bbf00] [c000000000024f64] .start_secondary+0x160/0x184 [c0000000047bbf90] [c0000000000083c0] .start_secondary_prolog+0xc/0x10 Instruction dump:
2f830000 419d0008 38600001 78630020 4e800020 38000014 7c6903d6 2f830000 419d0008 38600001 78630020 4e800020 <81240000> 39030030 3c000020 3d400010

Kernel panic - not syncing: Fatal exception in interrupt
------------[ cut here ]------------
Badness at arch/powerpc/kernel/smp.c:202
Call Trace:
[c0000000047ba9b0] [c00000000000e650] .show_stack+0x68/0x1b0 (unreliable)
[c0000000047baa50] [c00000000029eca0] .report_bug+0x94/0xe8
[c0000000047baae0] [c0000000000219f0] .program_check_exception+0x12c/0x568
[c0000000047bab60] [c000000000004a84] program_check_common+0x104/0x180
--- Exception: 700 at .smp_call_function_map+0x30/0x25c
    LR = .panic+0x8c/0x1a4

[c0000000047bae50] [c0000000005e3f48] 0xc0000000005e3f48 (unreliable) [c0000000047baf00] [c00000000004acc4] .panic+0x8c/0x1a4 [c0000000047bafa0] [c0000000000214f4] .die+0x198/0x1b0 [c0000000047bb040] [c0000000000282c8] .bad_page_fault+0xb8/0xd4 [c0000000047bb0c0] [c000000000004e98] handle_page_fault+0x3c/0x58 --- Exception: 300 at .dequeue_task+0x0/0x9c

    LR = .deactivate_task+0x40/0x60

[c0000000047bb3b0] [c00000000004bccc] .printk+0x38/0x48 (unreliable) [c0000000047bb440] [c000000000471704] .schedule+0x1fc/0x8dc [c0000000047bb540] [c000000000472c9c] .schedule_timeout+0xa8/0xe8 [c0000000047bb610] [c000000000057260] .msleep+0x20/0x38 [c0000000047bb690] [c00000000003f5ec] .eeh_dn_check_failure+0x114/0x268 [c0000000047bb740] [c00000000003fc64] .eeh_check_failure+0xec/0x114 [c0000000047bb7c0] [d00000000086190c] .qla2300_fw_dump+0x1130/0x1c00 [qla2xxx] [c0000000047bb8a0] [d000000000858d50] .qla2300_intr_handler+0x1e8/0x60c [qla2xxx] [c0000000047bb950] [c000000000078368] .handle_IRQ_event+0x70/0xe4 [c0000000047bb9f0] [c00000000007a7e0] .handle_fasteoi_irq+0x11c/0x1d0 [c0000000047bba90] [c00000000000c178] .do_IRQ+0x90/0xec [c0000000047bbb10] [c000000000004790] hardware_interrupt_entry+0x18/0x1c --- Exception: 501 at .ppc64_runlatch_off+0x20/0x50

    LR = .pseries_dedicated_idle_sleep+0x88/0x11c

[c0000000047bbe00] [c0000000047bbe80] 0xc0000000047bbe80 (unreliable) [c0000000047bbe80] [c0000000000108f4] .cpu_idle+0xc8/0x118 [c0000000047bbf00] [c000000000024f64] .start_secondary+0x160/0x184 [c0000000047bbf90] [c0000000000083c0] .start_secondary_prolog+0xc/0x10

author
#21 lore raw
Quoted 11 lines · Badari Pulavarty

arch/x86_64/kernel/pci-gart.c

Quoted 7 lines

If iommu=off works, can you try a normal boot but with this applied on top of the sglist patches? That should fix gart mapping.

arch/x86_64/kernel/pci-gart.c +0 -0
index 2e22a3a..b16384f 100644

Yes. With this patch + kzalloc() for ide probe took care of all my problems on x86-64.

Quoted 1 line

But my ppc64 box is still sick :(

:-(

Quoted 18 lines
Oops: Kernel access of bad area, sig: 11 [#1]
SMP NR_CPUS=32 NUMA pSeries
Modules linked in: qla2xxx scsi_transport_fc
NIP: c0000000000414a0 LR: c00000000004162c CTR: 0000000000000001
REGS: c0000000047bb130 TRAP: 0300   Not tainted  (2.6.22-rc1)
MSR: 8000000000001032 <ME,IR,DR>  CR: 28000022  XER: 00000008
DAR: 0000000000000000, DSISR: 0000000040000000

TASK = c0000000047a6aa0[0] 'swapper' THREAD: c0000000047b8000 CPU: 7
GPR00: 0000000000000080 c0000000047bb3b0 c000000000692358 c0000000047a6aa0
GPR04: 0000000000000000 0000000000000070 0000000000000000 c0000000005ac0b8
GPR08: 000000000000e4b4 0000000000000001 0000000000000000 0000000000000280
GPR12: 0000000000000020 c0000000005a3e80 0000000000000000 0000000007a8dd70
GPR16: 0000000000000000 0000000000000000 0000000000000000 c0000000047b8000
GPR20: 000000003b9aca00 c0000000047a6c50 0000000000000001 0000000000000000
GPR24: d000000000909048 0001dee6d30c0d30 c000000003b7dd80 c0000000047a6aa0
GPR28: 00000001079027ca c0000000047a6aa0 c0000000005b7cb0 c000000000472c9c NIP [c0000000000414a0] .dequeue_task+0x0/0x9c
LR [c00000000004162c] .deactivate_task+0x40/0x60

Quoted 13 lines
Call Trace:
[c0000000047bb3b0] [c00000000004bccc] .printk+0x38/0x48 (unreliable)
[c0000000047bb440] [c000000000471704] .schedule+0x1fc/0x8dc
[c0000000047bb540] [c000000000472c9c] .schedule_timeout+0xa8/0xe8
[c0000000047bb610] [c000000000057260] .msleep+0x20/0x38
[c0000000047bb690] [c00000000003f5ec] .eeh_dn_check_failure+0x114/0x268
[c0000000047bb740] [c00000000003fc64] .eeh_check_failure+0xec/0x114
[c0000000047bb7c0] [d00000000086190c] .qla2300_fw_dump+0x1130/0x1c00 [qla2xxx]
[c0000000047bb8a0] [d000000000858d50] .qla2300_intr_handler+0x1e8/0x60c [qla2xxx]
[c0000000047bb950] [c000000000078368] .handle_IRQ_event+0x70/0xe4
[c0000000047bb9f0] [c00000000007a7e0] .handle_fasteoi_irq+0x11c/0x1d0
[c0000000047bba90] [c00000000000c178] .do_IRQ+0x90/0xec
[c0000000047bbb10] [c000000000004790] hardware_interrupt_entry+0x18/0x1c

Not good. The qla changes are non-trivial (that hardware has a really funky sg setup), so I may have botched a part of it. I'll review the qla changes and get back to you.

Signature · 1 line
Jens Axboe
author
#23 lore raw
In reply to FUJITA Tomonori
Quoted 52 lines · FUJITA Tomonori

From: Jens Axboe <[email protected]>
Subject: Re: [PATCH] Chaining sg lists for big IO commands v5
Date: Thu, 24 May 2007 11:34:41 +0200

Quoted 48 lines · Badari Pulavarty
Quoted 11 lines

arch/x86_64/kernel/pci-gart.c

Quoted 7 lines

If iommu=off works, can you try a normal boot but with this applied on top of the sglist patches? That should fix gart mapping.

arch/x86_64/kernel/pci-gart.c +0 -0
index 2e22a3a..b16384f 100644

Yes. With this patch + kzalloc() for ide probe took care of all my problems on x86-64.

Quoted 1 line

But my ppc64 box is still sick :(

:-(

Quoted 31 lines
Oops: Kernel access of bad area, sig: 11 [#1]
SMP NR_CPUS=32 NUMA pSeries
Modules linked in: qla2xxx scsi_transport_fc
NIP: c0000000000414a0 LR: c00000000004162c CTR: 0000000000000001
REGS: c0000000047bb130 TRAP: 0300   Not tainted  (2.6.22-rc1)
MSR: 8000000000001032 <ME,IR,DR>  CR: 28000022  XER: 00000008
DAR: 0000000000000000, DSISR: 0000000040000000

TASK = c0000000047a6aa0[0] 'swapper' THREAD: c0000000047b8000 CPU: 7
GPR00: 0000000000000080 c0000000047bb3b0 c000000000692358 c0000000047a6aa0
GPR04: 0000000000000000 0000000000000070 0000000000000000 c0000000005ac0b8
GPR08: 000000000000e4b4 0000000000000001 0000000000000000 0000000000000280
GPR12: 0000000000000020 c0000000005a3e80 0000000000000000 0000000007a8dd70
GPR16: 0000000000000000 0000000000000000 0000000000000000 c0000000047b8000
GPR20: 000000003b9aca00 c0000000047a6c50 0000000000000001 0000000000000000
GPR24: d000000000909048 0001dee6d30c0d30 c000000003b7dd80 c0000000047a6aa0
GPR28: 00000001079027ca c0000000047a6aa0 c0000000005b7cb0 c000000000472c9c NIP [c0000000000414a0] .dequeue_task+0x0/0x9c
LR [c00000000004162c] .deactivate_task+0x40/0x60

Call Trace:
[c0000000047bb3b0] [c00000000004bccc] .printk+0x38/0x48 (unreliable)
[c0000000047bb440] [c000000000471704] .schedule+0x1fc/0x8dc
[c0000000047bb540] [c000000000472c9c] .schedule_timeout+0xa8/0xe8
[c0000000047bb610] [c000000000057260] .msleep+0x20/0x38
[c0000000047bb690] [c00000000003f5ec] .eeh_dn_check_failure+0x114/0x268
[c0000000047bb740] [c00000000003fc64] .eeh_check_failure+0xec/0x114
[c0000000047bb7c0] [d00000000086190c] .qla2300_fw_dump+0x1130/0x1c00 [qla2xxx]
[c0000000047bb8a0] [d000000000858d50] .qla2300_intr_handler+0x1e8/0x60c [qla2xxx]
[c0000000047bb950] [c000000000078368] .handle_IRQ_event+0x70/0xe4
[c0000000047bb9f0] [c00000000007a7e0] .handle_fasteoi_irq+0x11c/0x1d0
[c0000000047bba90] [c00000000000c178] .do_IRQ+0x90/0xec
[c0000000047bbb10] [c000000000004790] hardware_interrupt_entry+0x18/0x1c
Quoted 8 lines
Quoted 3 lines

Not good. The qla changes are non-trivial (that hardware has a really funky sg setup), so I may have botched a part of it. I'll review the qla changes and get back to you.

I guess that qla2xxx needs more for_each_sg macros. My qla2xxx cleanup patch might help:

http://git.kernel.org/?p=linux/kernel/git/tomo/linux-2.6-bidi.git;a=commitdiff;h=fb2747a9f2465ac4a1ea9e3533b92510fbcaae0c

Neat, will take a look! I should be able to just reuse that.

Signature · 1 line
Jens Axboe
#22 lore raw
In reply to Jens Axboe

From: Jens Axboe <[email protected]>
Subject: Re: [PATCH] Chaining sg lists for big IO commands v5
Date: Thu, 24 May 2007 11:34:41 +0200

Quoted 48 lines · Badari Pulavarty
Quoted 11 lines

arch/x86_64/kernel/pci-gart.c

Quoted 7 lines

If iommu=off works, can you try a normal boot but with this applied on top of the sglist patches? That should fix gart mapping.

arch/x86_64/kernel/pci-gart.c +0 -0
index 2e22a3a..b16384f 100644

Yes. With this patch + kzalloc() for ide probe took care of all my problems on x86-64.

Quoted 1 line

But my ppc64 box is still sick :(

:-(

Quoted 18 lines
Oops: Kernel access of bad area, sig: 11 [#1]
SMP NR_CPUS=32 NUMA pSeries
Modules linked in: qla2xxx scsi_transport_fc
NIP: c0000000000414a0 LR: c00000000004162c CTR: 0000000000000001
REGS: c0000000047bb130 TRAP: 0300   Not tainted  (2.6.22-rc1)
MSR: 8000000000001032 <ME,IR,DR>  CR: 28000022  XER: 00000008
DAR: 0000000000000000, DSISR: 0000000040000000

TASK = c0000000047a6aa0[0] 'swapper' THREAD: c0000000047b8000 CPU: 7
GPR00: 0000000000000080 c0000000047bb3b0 c000000000692358 c0000000047a6aa0
GPR04: 0000000000000000 0000000000000070 0000000000000000 c0000000005ac0b8
GPR08: 000000000000e4b4 0000000000000001 0000000000000000 0000000000000280
GPR12: 0000000000000020 c0000000005a3e80 0000000000000000 0000000007a8dd70
GPR16: 0000000000000000 0000000000000000 0000000000000000 c0000000047b8000
GPR20: 000000003b9aca00 c0000000047a6c50 0000000000000001 0000000000000000
GPR24: d000000000909048 0001dee6d30c0d30 c000000003b7dd80 c0000000047a6aa0
GPR28: 00000001079027ca c0000000047a6aa0 c0000000005b7cb0 c000000000472c9c NIP [c0000000000414a0] .dequeue_task+0x0/0x9c
LR [c00000000004162c] .deactivate_task+0x40/0x60

Quoted 13 lines
Call Trace:
[c0000000047bb3b0] [c00000000004bccc] .printk+0x38/0x48 (unreliable)
[c0000000047bb440] [c000000000471704] .schedule+0x1fc/0x8dc
[c0000000047bb540] [c000000000472c9c] .schedule_timeout+0xa8/0xe8
[c0000000047bb610] [c000000000057260] .msleep+0x20/0x38
[c0000000047bb690] [c00000000003f5ec] .eeh_dn_check_failure+0x114/0x268
[c0000000047bb740] [c00000000003fc64] .eeh_check_failure+0xec/0x114
[c0000000047bb7c0] [d00000000086190c] .qla2300_fw_dump+0x1130/0x1c00 [qla2xxx]
[c0000000047bb8a0] [d000000000858d50] .qla2300_intr_handler+0x1e8/0x60c [qla2xxx]
[c0000000047bb950] [c000000000078368] .handle_IRQ_event+0x70/0xe4
[c0000000047bb9f0] [c00000000007a7e0] .handle_fasteoi_irq+0x11c/0x1d0
[c0000000047bba90] [c00000000000c178] .do_IRQ+0x90/0xec
[c0000000047bbb10] [c000000000004790] hardware_interrupt_entry+0x18/0x1c
Quoted 3 lines

Not good. The qla changes are non-trivial (that hardware has a really funky sg setup), so I may have botched a part of it. I'll review the qla changes and get back to you.

I guess that qla2xxx needs more for_each_sg macros. My qla2xxx cleanup patch might help:

http://git.kernel.org/?p=linux/kernel/git/tomo/linux-2.6-bidi.git;a=commitdiff;h=fb2747a9f2465ac4a1ea9e3533b92510fbcaae0c

author
#30 lore raw
In reply to Jens Axboe
Quoted 32 lines · Jens Axboe
Quoted 18 lines
Oops: Kernel access of bad area, sig: 11 [#1]
SMP NR_CPUS=32 NUMA pSeries
Modules linked in: qla2xxx scsi_transport_fc
NIP: c0000000000414a0 LR: c00000000004162c CTR: 0000000000000001
REGS: c0000000047bb130 TRAP: 0300   Not tainted  (2.6.22-rc1)
MSR: 8000000000001032 <ME,IR,DR>  CR: 28000022  XER: 00000008
DAR: 0000000000000000, DSISR: 0000000040000000

TASK = c0000000047a6aa0[0] 'swapper' THREAD: c0000000047b8000 CPU: 7
GPR00: 0000000000000080 c0000000047bb3b0 c000000000692358 c0000000047a6aa0
GPR04: 0000000000000000 0000000000000070 0000000000000000 c0000000005ac0b8
GPR08: 000000000000e4b4 0000000000000001 0000000000000000 0000000000000280
GPR12: 0000000000000020 c0000000005a3e80 0000000000000000 0000000007a8dd70
GPR16: 0000000000000000 0000000000000000 0000000000000000 c0000000047b8000
GPR20: 000000003b9aca00 c0000000047a6c50 0000000000000001 0000000000000000
GPR24: d000000000909048 0001dee6d30c0d30 c000000003b7dd80 c0000000047a6aa0
GPR28: 00000001079027ca c0000000047a6aa0 c0000000005b7cb0 c000000000472c9c NIP [c0000000000414a0] .dequeue_task+0x0/0x9c
LR [c00000000004162c] .deactivate_task+0x40/0x60

Quoted 13 lines
Call Trace:
[c0000000047bb3b0] [c00000000004bccc] .printk+0x38/0x48 (unreliable)
[c0000000047bb440] [c000000000471704] .schedule+0x1fc/0x8dc
[c0000000047bb540] [c000000000472c9c] .schedule_timeout+0xa8/0xe8
[c0000000047bb610] [c000000000057260] .msleep+0x20/0x38
[c0000000047bb690] [c00000000003f5ec] .eeh_dn_check_failure+0x114/0x268
[c0000000047bb740] [c00000000003fc64] .eeh_check_failure+0xec/0x114
[c0000000047bb7c0] [d00000000086190c] .qla2300_fw_dump+0x1130/0x1c00 [qla2xxx]
[c0000000047bb8a0] [d000000000858d50] .qla2300_intr_handler+0x1e8/0x60c [qla2xxx]
[c0000000047bb950] [c000000000078368] .handle_IRQ_event+0x70/0xe4
[c0000000047bb9f0] [c00000000007a7e0] .handle_fasteoi_irq+0x11c/0x1d0
[c0000000047bba90] [c00000000000c178] .do_IRQ+0x90/0xec
[c0000000047bbb10] [c000000000004790] hardware_interrupt_entry+0x18/0x1c
Quoted 3 lines

Not good. The qla changes are non-trivial (that hardware has a really funky sg setup), so I may have botched a part of it. I'll review the qla changes and get back to you.

Does this help?

drivers/scsi/qla2xxx/qla_iocb.c +21 -28
index 10251bf..5510b86 100644
@@ -155,6 +155,8 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
 	uint32_t	*cur_dsd;
 	scsi_qla_host_t	*ha;
 	struct scsi_cmnd *cmd;
+	struct scatterlist *sg;
+	int i;
 
 	cmd = sp->cmd;
 
@@ -178,13 +180,10 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
 
 	/* Load data segments */
 	if (cmd->use_sg != 0) {
-		struct	scatterlist *cur_seg;
-		struct	scatterlist *end_seg;
-
-		cur_seg = (struct scatterlist *)cmd->request_buffer;
-		end_seg = cur_seg + tot_dsds;
-		while (cur_seg < end_seg) {
-			cont_entry_t	*cont_pkt;
+		struct scatterlist *sgl = cmd->request_buffer;
+	
+		for_each_sg(sgl, sg, tot_dsds, i) {
+			cont_entry_t *cont_pkt;
 
 			/* Allocate additional continuation packets? */
 			if (avail_dsds == 0) {
@@ -197,11 +196,9 @@ void qla2x00_build_scsi_iocbs_32(srb_t *sp, cmd_entry_t *cmd_pkt,
 				avail_dsds = 7;
 			}
 
-			*cur_dsd++ = cpu_to_le32(sg_dma_address(cur_seg));
-			*cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg));
+			*cur_dsd++ = cpu_to_le32(sg_dma_address(sg));
+			*cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
 			avail_dsds--;
-
-			cur_seg++;
 		}
 	} else {
 		*cur_dsd++ = cpu_to_le32(sp->dma_handle);
@@ -224,6 +221,9 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
 	uint32_t	*cur_dsd;
 	scsi_qla_host_t	*ha;
 	struct scsi_cmnd *cmd;
+	struct scatterlist *sgl;
+	struct scatterlist *sg;
+	int i;
 
 	cmd = sp->cmd;
 
@@ -247,12 +247,8 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
 
 	/* Load data segments */
 	if (cmd->use_sg != 0) {
-		struct	scatterlist *cur_seg;
-		struct	scatterlist *end_seg;
-
-		cur_seg = (struct scatterlist *)cmd->request_buffer;
-		end_seg = cur_seg + tot_dsds;
-		while (cur_seg < end_seg) {
+		sgl = cmd->request_buffer;
+		for_each_sg(sgl, sg, tot_dsds, i) {
 			dma_addr_t	sle_dma;
 			cont_a64_entry_t *cont_pkt;
 
@@ -267,13 +263,11 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
 				avail_dsds = 5;
 			}
 
-			sle_dma = sg_dma_address(cur_seg);
+			sle_dma = sg_dma_address(sg);
 			*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
 			*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
-			*cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg));
+			*cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
 			avail_dsds--;
-
-			cur_seg++;
 		}
 	} else {
 		*cur_dsd++ = cpu_to_le32(LSD(sp->dma_handle));
@@ -642,6 +636,8 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
 	uint32_t	*cur_dsd;
 	scsi_qla_host_t	*ha;
 	struct scsi_cmnd *cmd;
+	struct scatterlist *sg, *sgl;
+	int i;
 
 	cmd = sp->cmd;
 
@@ -671,11 +667,8 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
 
 	/* Load data segments */
 	if (cmd->use_sg != 0) {
-		struct	scatterlist *sgl = cmd->request_buffer;
-		struct	scatterlist *cur_seg;
-		int i;
-
-		for_each_sg(sgl, cur_seg, tot_dsds, i) {
+		sgl = cmd->request_buffer;
+		for_each_sg(sgl, sg, tot_dsds, i) {
 			dma_addr_t	sle_dma;
 			cont_a64_entry_t *cont_pkt;
 
@@ -690,10 +683,10 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt,
 				avail_dsds = 5;
 			}
 
-			sle_dma = sg_dma_address(cur_seg);
+			sle_dma = sg_dma_address(sg);
 			*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
 			*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
-			*cur_dsd++ = cpu_to_le32(sg_dma_len(cur_seg));
+			*cur_dsd++ = cpu_to_le32(sg_dma_len(sg));
 			avail_dsds--;
 		}
 	} else {
Signature · 1 line
Jens Axboe
#25 lore raw

(cc's added)

From: Jens Axboe <[email protected]>
Subject: Re: [PATCH] Chaining sg lists for big IO commands v5
Date: Thu, 24 May 2007 14:05:54 +0200

Quoted 8 lines · Jens Axboe
Quoted 3 lines
Quoted 1 line

http://git.kernel.org/?p=linux/kernel/git/tomo/linux-2.6-bidi.git;a=commitdiff;h=fb2747a9f2465ac4a1ea9e3533b92510fbcaae0c

Neat, will take a look! I should be able to just reuse that.

BTW, when do you plan on pushing the SCSI sg update? I'd love for it to be soon, so I can just rebase the sglist branch on that and get rid of the SCSI stuff in there.

Well, all I can say is that I'd love James to push the cleanups patchset soon too.

author
#26 lore raw
Quoted 9 lines · FUJITA Tomonori

(cc's added)

From: Jens Axboe <[email protected]>
Subject: Re: [PATCH] Chaining sg lists for big IO commands v5
Date: Thu, 24 May 2007 14:05:54 +0200

Quoted 3 lines · Jens Axboe
Quoted 2 lines
Quoted 1 line

http://git.kernel.org/?p=linux/kernel/git/tomo/linux-2.6-bidi.git;a=commitdiff;h=fb2747a9f2465ac4a1ea9e3533b92510fbcaae0c

Quoted 8 lines
Quoted 5 lines
Quoted 1 line

Neat, will take a look! I should be able to just reuse that.

BTW, when do you plan on pushing the SCSI sg update? I'd love for it to be soon, so I can just rebase the sglist branch on that and get rid of the SCSI stuff in there.

Well, all I can say is that I'd love James to push the cleanups patchset soon too.

Cool, James?

Signature · 1 line
Jens Axboe
#31 lore raw
In reply to Jens Axboe

drivers/scsi/qla2xxx/qla_iocb.c

Quoted 40 lines · Jens Axboe
Quoted 32 lines · Jens Axboe
Quoted 18 lines
Oops: Kernel access of bad area, sig: 11 [#1]
SMP NR_CPUS=32 NUMA pSeries
Modules linked in: qla2xxx scsi_transport_fc
NIP: c0000000000414a0 LR: c00000000004162c CTR: 0000000000000001
REGS: c0000000047bb130 TRAP: 0300   Not tainted  (2.6.22-rc1)
MSR: 8000000000001032 <ME,IR,DR>  CR: 28000022  XER: 00000008
DAR: 0000000000000000, DSISR: 0000000040000000

TASK = c0000000047a6aa0[0] 'swapper' THREAD: c0000000047b8000 CPU: 7
GPR00: 0000000000000080 c0000000047bb3b0 c000000000692358 c0000000047a6aa0
GPR04: 0000000000000000 0000000000000070 0000000000000000 c0000000005ac0b8
GPR08: 000000000000e4b4 0000000000000001 0000000000000000 0000000000000280
GPR12: 0000000000000020 c0000000005a3e80 0000000000000000 0000000007a8dd70
GPR16: 0000000000000000 0000000000000000 0000000000000000 c0000000047b8000
GPR20: 000000003b9aca00 c0000000047a6c50 0000000000000001 0000000000000000
GPR24: d000000000909048 0001dee6d30c0d30 c000000003b7dd80 c0000000047a6aa0
GPR28: 00000001079027ca c0000000047a6aa0 c0000000005b7cb0 c000000000472c9c NIP [c0000000000414a0] .dequeue_task+0x0/0x9c
LR [c00000000004162c] .deactivate_task+0x40/0x60

Quoted 13 lines
Call Trace:
[c0000000047bb3b0] [c00000000004bccc] .printk+0x38/0x48 (unreliable)
[c0000000047bb440] [c000000000471704] .schedule+0x1fc/0x8dc
[c0000000047bb540] [c000000000472c9c] .schedule_timeout+0xa8/0xe8
[c0000000047bb610] [c000000000057260] .msleep+0x20/0x38
[c0000000047bb690] [c00000000003f5ec] .eeh_dn_check_failure+0x114/0x268
[c0000000047bb740] [c00000000003fc64] .eeh_check_failure+0xec/0x114
[c0000000047bb7c0] [d00000000086190c] .qla2300_fw_dump+0x1130/0x1c00 [qla2xxx]
[c0000000047bb8a0] [d000000000858d50] .qla2300_intr_handler+0x1e8/0x60c [qla2xxx]
[c0000000047bb950] [c000000000078368] .handle_IRQ_event+0x70/0xe4
[c0000000047bb9f0] [c00000000007a7e0] .handle_fasteoi_irq+0x11c/0x1d0
[c0000000047bba90] [c00000000000c178] .do_IRQ+0x90/0xec
[c0000000047bbb10] [c000000000004790] hardware_interrupt_entry+0x18/0x1c
Quoted 3 lines

Not good. The qla changes are non-trivial (that hardware has a really funky sg setup), so I may have botched a part of it. I'll review the qla changes and get back to you.

Does this help?

drivers/scsi/qla2xxx/qla_iocb.c +0 -0

Yes. It does. For now, I have no more complaints :)

Thanks,
Badari

#27 lore raw
In reply to FUJITA Tomonori
Quoted 9 lines · FUJITA Tomonori

(cc's added)

From: Jens Axboe <[email protected]>
Subject: Re: [PATCH] Chaining sg lists for big IO commands v5
Date: Thu, 24 May 2007 14:05:54 +0200

Quoted 3 lines · Jens Axboe
Quoted 2 lines
Quoted 1 line

http://git.kernel.org/?p=linux/kernel/git/tomo/linux-2.6-bidi.git;a=commitdiff;h=fb2747a9f2465ac4a1ea9e3533b92510fbcaae0c

Quoted 8 lines
Quoted 5 lines
Quoted 1 line

Neat, will take a look! I should be able to just reuse that.

BTW, when do you plan on pushing the SCSI sg update? I'd love for it to be soon, so I can just rebase the sglist branch on that and get rid of the SCSI stuff in there.

Well, all I can say is that I'd love James to push the cleanups patchset soon too.

I'll put the accessor one into scsi-misc. I'll try to get the other 40 reviewed via the scsi-pending tree that Mark Salyzyn suggested ... give me some time on that.

James

#28 lore raw

From: James Bottomley <[email protected]>
Subject: Re: [PATCH] Chaining sg lists for big IO commands v5
Date: Thu, 24 May 2007 10:39:44 -0500

Quoted 16 lines · FUJITA Tomonori
Quoted 15 lines

(cc's added)

From: Jens Axboe <[email protected]>
Subject: Re: [PATCH] Chaining sg lists for big IO commands v5
Date: Thu, 24 May 2007 14:05:54 +0200

Quoted 8 lines · Jens Axboe
Quoted 3 lines
Quoted 1 line

http://git.kernel.org/?p=linux/kernel/git/tomo/linux-2.6-bidi.git;a=commitdiff;h=fb2747a9f2465ac4a1ea9e3533b92510fbcaae0c

Neat, will take a look! I should be able to just reuse that.

BTW, when do you plan on pushing the SCSI sg update? I'd love for it to be soon, so I can just rebase the sglist branch on that and get rid of the SCSI stuff in there.

Quoted 6 lines
Quoted 2 lines

Well, all I can say is that I'd love James to push the cleanups patchset soon too.

I'll put the accessor one into scsi-misc. I'll try to get the other 40 reviewed via the scsi-pending tree that Mark Salyzyn suggested ... give me some time on that.

Thanks. Do you want me to send the patches to scsi-ml or you directly get them via the git tree?

#29 lore raw
Quoted 23 lines · FUJITA Tomonori

From: James Bottomley <[email protected]>
Subject: Re: [PATCH] Chaining sg lists for big IO commands v5
Date: Thu, 24 May 2007 10:39:44 -0500

Quoted 19 lines · FUJITA Tomonori
Quoted 17 lines

(cc's added)

From: Jens Axboe <[email protected]>
Subject: Re: [PATCH] Chaining sg lists for big IO commands v5
Date: Thu, 24 May 2007 14:05:54 +0200

Quoted 8 lines · Jens Axboe
Quoted 3 lines
Quoted 1 line

http://git.kernel.org/?p=linux/kernel/git/tomo/linux-2.6-bidi.git;a=commitdiff;h=fb2747a9f2465ac4a1ea9e3533b92510fbcaae0c

Neat, will take a look! I should be able to just reuse that.

BTW, when do you plan on pushing the SCSI sg update? I'd love for it to be soon, so I can just rebase the sglist branch on that and get rid of the SCSI stuff in there.

Well, all I can say is that I'd love James to push the cleanups patchset soon too.

Quoted 6 lines
Quoted 3 lines

I'll put the accessor one into scsi-misc. I'll try to get the other 40 reviewed via the scsi-pending tree that Mark Salyzyn suggested ... give me some time on that.

Thanks. Do you want me to send the patches to scsi-ml or you directly get them via the git tree?

Either works ... but for 40 patches it was easier for me to fetch into a git branch and cherry pick the two that can go into scsi-misc now.

I'm just correcting a compile warning on the 53c700 one, then I'll push.

James

author
#32 lore raw
In reply to Badari Pulavarty
Quoted 38 lines · Badari Pulavarty
Quoted 37 lines · Jens Axboe
Quoted 35 lines · Jens Axboe
Quoted 18 lines
Oops: Kernel access of bad area, sig: 11 [#1]
SMP NR_CPUS=32 NUMA pSeries
Modules linked in: qla2xxx scsi_transport_fc
NIP: c0000000000414a0 LR: c00000000004162c CTR: 0000000000000001
REGS: c0000000047bb130 TRAP: 0300   Not tainted  (2.6.22-rc1)
MSR: 8000000000001032 <ME,IR,DR>  CR: 28000022  XER: 00000008
DAR: 0000000000000000, DSISR: 0000000040000000

TASK = c0000000047a6aa0[0] 'swapper' THREAD: c0000000047b8000 CPU: 7
GPR00: 0000000000000080 c0000000047bb3b0 c000000000692358 c0000000047a6aa0
GPR04: 0000000000000000 0000000000000070 0000000000000000 c0000000005ac0b8
GPR08: 000000000000e4b4 0000000000000001 0000000000000000 0000000000000280
GPR12: 0000000000000020 c0000000005a3e80 0000000000000000 0000000007a8dd70
GPR16: 0000000000000000 0000000000000000 0000000000000000 c0000000047b8000
GPR20: 000000003b9aca00 c0000000047a6c50 0000000000000001 0000000000000000
GPR24: d000000000909048 0001dee6d30c0d30 c000000003b7dd80 c0000000047a6aa0
GPR28: 00000001079027ca c0000000047a6aa0 c0000000005b7cb0 c000000000472c9c NIP [c0000000000414a0] .dequeue_task+0x0/0x9c
LR [c00000000004162c] .deactivate_task+0x40/0x60

Quoted 13 lines
Call Trace:
[c0000000047bb3b0] [c00000000004bccc] .printk+0x38/0x48 (unreliable)
[c0000000047bb440] [c000000000471704] .schedule+0x1fc/0x8dc
[c0000000047bb540] [c000000000472c9c] .schedule_timeout+0xa8/0xe8
[c0000000047bb610] [c000000000057260] .msleep+0x20/0x38
[c0000000047bb690] [c00000000003f5ec] .eeh_dn_check_failure+0x114/0x268
[c0000000047bb740] [c00000000003fc64] .eeh_check_failure+0xec/0x114
[c0000000047bb7c0] [d00000000086190c] .qla2300_fw_dump+0x1130/0x1c00 [qla2xxx]
[c0000000047bb8a0] [d000000000858d50] .qla2300_intr_handler+0x1e8/0x60c [qla2xxx]
[c0000000047bb950] [c000000000078368] .handle_IRQ_event+0x70/0xe4
[c0000000047bb9f0] [c00000000007a7e0] .handle_fasteoi_irq+0x11c/0x1d0
[c0000000047bba90] [c00000000000c178] .do_IRQ+0x90/0xec
[c0000000047bbb10] [c000000000004790] hardware_interrupt_entry+0x18/0x1c

Not good. The qla changes are non-trivial (that hardware has a really funky sg setup), so I may have botched a part of it. I'll review the qla changes and get back to you.

Quoted 5 lines

drivers/scsi/qla2xxx/qla_iocb.c

Quoted 3 lines

Does this help?

drivers/scsi/qla2xxx/qla_iocb.c +0 -0

Yes. It does. For now, I have no more complaints :)

Excellent! Let me know if you manage to run some performance numbers.

Signature · 1 line
Jens Axboe