Message ID | 1374215660.7397.1041.camel@haakon3.risingtidesystems.com |
---|---|
State | Not Applicable |
Delegated to: | David Miller |
Headers | show |
On Thu, 2013-07-18 at 23:34 -0700, Nicholas A. Bellinger wrote: > diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c > index 0101af5..191bc15 100644 > --- a/drivers/ata/libata-scsi.c > +++ b/drivers/ata/libata-scsi.c > @@ -1144,7 +1144,11 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, > "sector_size=%u > PAGE_SIZE, PIO may malfunction\n", > sdev->sector_size); > > - blk_queue_update_dma_alignment(q, sdev->sector_size - 1); > + if (!q->mq_ops) { > + blk_queue_update_dma_alignment(q, sdev->sector_size - 1); > + } else { > + printk("Skipping dma_alignment for libata w/ scsi-mq\n"); > + } Amazingly enough there is a reason for the dma alignment, and it wasn't just to annoy you, so you can't blindly do this. The email thread is probably lost in the mists of time, but if I remember correctly the problem is that some ahci DMA controllers barf if the sector they're doing DMA on crosses a page boundary. Some are annoying enough to actually cause silent data corruption. You won't find every ahci DMA controller doing this, so the change will work for some, but it will be hard to identify those it won't work for until people start losing data. The correct fix, obviously, is to do the bio copy on the kernel path for unaligned data. It is OK to assume that REQ_TYPE_FS data is correctly aligned (because of the block to page alignment). James -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, 2013-07-19 at 08:33 -0700, James Bottomley wrote: > On Thu, 2013-07-18 at 23:34 -0700, Nicholas A. Bellinger wrote: > > diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c > > index 0101af5..191bc15 100644 > > --- a/drivers/ata/libata-scsi.c > > +++ b/drivers/ata/libata-scsi.c > > @@ -1144,7 +1144,11 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, > > "sector_size=%u > PAGE_SIZE, PIO may malfunction\n", > > sdev->sector_size); > > > > - blk_queue_update_dma_alignment(q, sdev->sector_size - 1); > > + if (!q->mq_ops) { > > + blk_queue_update_dma_alignment(q, sdev->sector_size - 1); > > + } else { > > + printk("Skipping dma_alignment for libata w/ scsi-mq\n"); > > + } > > Amazingly enough there is a reason for the dma alignment, and it wasn't > just to annoy you, so you can't blindly do this. > > The email thread is probably lost in the mists of time, but if I > remember correctly the problem is that some ahci DMA controllers barf if > the sector they're doing DMA on crosses a page boundary. Some are > annoying enough to actually cause silent data corruption. You won't > find every ahci DMA controller doing this, so the change will work for > some, but it will be hard to identify those it won't work for until > people start losing data. Thanks for the extra background. So at least from what I gather thus far this shouldn't be an issue for initial testing with scsi-mq <-> libata w/ ata_piix. > > The correct fix, obviously, is to do the bio copy on the kernel path for > unaligned data. It is OK to assume that REQ_TYPE_FS data is correctly > aligned (because of the block to page alignment). > Indeed. Looking into the bio_copy_kern() breakage next.. --nab -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 9a8a674..ac05cd6 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -1066,6 +1066,8 @@ static u8 piix_vmw_bmdma_status(struct ata_port *ap) static struct scsi_host_template piix_sht = { ATA_BMDMA_SHT(DRV_NAME), + .scsi_mq = true, + .queuecommand_mq = ata_scsi_queuecmd, }; static struct ata_port_operations piix_sata_ops = { diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 0101af5..191bc15 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1144,7 +1144,11 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, "sector_size=%u > PAGE_SIZE, PIO may malfunction\n", sdev->sector_size); - blk_queue_update_dma_alignment(q, sdev->sector_size - 1); + if (!q->mq_ops) { + blk_queue_update_dma_alignment(q, sdev->sector_size - 1); + } else { + printk("Skipping dma_alignment for libata w/ scsi-mq\n"); + } if (dev->flags & ATA_DFLAG_AN) set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events); diff --git a/drivers/scsi/scsi-mq.c b/drivers/scsi/scsi-mq.c index ca6ff67..81b2633 100644 --- a/drivers/scsi/scsi-mq.c +++ b/drivers/scsi/scsi-mq.c @@ -199,11 +199,11 @@ int scsi_mq_alloc_queue(struct Scsi_Host *sh, struct scsi_device *sdev) int i, j; sdev->sdev_mq_reg.ops = &scsi_mq_ops; - sdev->sdev_mq_reg.queue_depth = sdev->queue_depth; + sdev->sdev_mq_reg.queue_depth = min((short)sh->hostt->can_queue, + sh->hostt->cmd_per_lun); sdev->sdev_mq_reg.cmd_size = sizeof(struct scsi_cmnd) + sh->hostt->cmd_size; sdev->sdev_mq_reg.numa_node = NUMA_NO_NODE; sdev->sdev_mq_reg.nr_hw_queues = 1; - sdev->sdev_mq_reg.queue_depth = 64; sdev->sdev_mq_reg.flags = BLK_MQ_F_SHOULD_MERGE; printk("Calling blk_mq_init_queue: scsi_mq_ops: %p, queue_depth: %d,"