Re: [PATCH] libata: eliminate the home grown dma padding in favour of that provided by the block layer

2008-01-09 Thread James Bottomley

On Wed, 2008-01-09 at 14:13 +0900, Tejun Heo wrote:
 James Bottomley wrote:
   Also, DMA alignment at
  block layer isn't enough for ATA.  ATA needs drain buffers for ATAPI
  commands with variable length response.  :-(
  
  OK, where is this in the libata code?  The dma_pad size is only 4 bytes,
  so this drain, I assume is only a word long?  Given the word alignment
  requirements of ATA doesn't this still mean it's only draining up to the
  word boundary anyway (so the code is still correct)?
 
 Patch is acked but not merged yet.
 
 http://git.kernel.org/?p=linux/kernel/git/tj/libata-dev.git;a=commit;h=6cd22a0febc74bebe52d58eb22271b8770892a2d
 
 The full function can be read from the following.  It's
 ata_sg_setup_extra().
 
 http://git.kernel.org/?p=linux/kernel/git/tj/libata-dev.git;a=blob;f=drivers/ata/libata-core.c;h=d763c072e6cefc724ea24cb68a7adf47b340f054;hb=6cd22a0febc74bebe52d58eb22271b8770892a2d

OK, but that patch was sent to the mailing list on 4 Jan ... five days
after this one.  It's a little hard to take unposted patches into
account ...

It's a fairly comprehensive merge clash ... where is this drain patch on
the upstream track?  because currently ipr and aic94xx panic the system
without the dma padding removal (I just figured -rc6 was a bit late for
major surgery like this, but I was planning a backport if it stood up in
2.6.24).

James


-
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] libata: eliminate the home grown dma padding in favour of that provided by the block layer

2008-01-08 Thread Tejun Heo
James Bottomley wrote:
 ATA requires that all DMA transfers begin and end on word boundaries.
 Because of this, a large amount of machinery grew up in ide to adjust
 scatterlists on this basis.  However, as of 2.5, the block layer has a
 dma_alignment variable which ensures both the beginning and length of a
 DMA transfer are aligned on the dma_alignment boundary.  Although the
 block layer does adjust the beginning of the transfer to ensure this
 happens, it doesn't actually adjust the length, it merely makes sure
 that space is allocated for transfers beyond the declared length.  The
 upshot of this is that scatterlists may be padded to any size between
 the actual length and the length adjusted to the dma_alignment safely
 knowing that memory is allocated in this region.
 
 Right at the moment, SCSI takes the default dma_aligment which is on a
 512 byte boundary.  Note that this aligment only applies to transfers
 coming in from user space.  However, since all kernel allocations are
 automatically aligned on a minimum of 32 byte boundaries, it is safe to
 adjust them in this manner as well.
 
 Signed-off-by: James Bottomley [EMAIL PROTECTED]
 
 ---
 
 This also fixes a current panic in libsas with SATAPI devices.  I was
 trying to trace a bad interaction between the libata padding and the new
 sglist code which was the root cause, and ended up concluding that the
 whole libata padding thing was redundant.
 
 In a future improvement, I think we can relax SCSI dma_alignemnt (it's
 causing almost every user space command to be copied instead of directly
 passed through) and allow devices and transports to build up their own
 requirements instead.

Great but this intersects with currently queued and pending changes for
libata-dev#upstream and needs to be merged.  Also, DMA alignment at
block layer isn't enough for ATA.  ATA needs drain buffers for ATAPI
commands with variable length response.  :-(

-- 
tejun
-
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] libata: eliminate the home grown dma padding in favour of that provided by the block layer

2008-01-08 Thread James Bottomley

On Wed, 2008-01-09 at 11:10 +0900, Tejun Heo wrote:
 James Bottomley wrote:
  ATA requires that all DMA transfers begin and end on word boundaries.
  Because of this, a large amount of machinery grew up in ide to adjust
  scatterlists on this basis.  However, as of 2.5, the block layer has a
  dma_alignment variable which ensures both the beginning and length of a
  DMA transfer are aligned on the dma_alignment boundary.  Although the
  block layer does adjust the beginning of the transfer to ensure this
  happens, it doesn't actually adjust the length, it merely makes sure
  that space is allocated for transfers beyond the declared length.  The
  upshot of this is that scatterlists may be padded to any size between
  the actual length and the length adjusted to the dma_alignment safely
  knowing that memory is allocated in this region.
  
  Right at the moment, SCSI takes the default dma_aligment which is on a
  512 byte boundary.  Note that this aligment only applies to transfers
  coming in from user space.  However, since all kernel allocations are
  automatically aligned on a minimum of 32 byte boundaries, it is safe to
  adjust them in this manner as well.
  
  Signed-off-by: James Bottomley [EMAIL PROTECTED]
  
  ---
  
  This also fixes a current panic in libsas with SATAPI devices.  I was
  trying to trace a bad interaction between the libata padding and the new
  sglist code which was the root cause, and ended up concluding that the
  whole libata padding thing was redundant.
  
  In a future improvement, I think we can relax SCSI dma_alignemnt (it's
  causing almost every user space command to be copied instead of directly
  passed through) and allow devices and transports to build up their own
  requirements instead.
 
 Great but this intersects with currently queued and pending changes for
 libata-dev#upstream and needs to be merged. 

That's OK, I can do the merge .. that's what git is for.

  Also, DMA alignment at
 block layer isn't enough for ATA.  ATA needs drain buffers for ATAPI
 commands with variable length response.  :-(

OK, where is this in the libata code?  The dma_pad size is only 4 bytes,
so this drain, I assume is only a word long?  Given the word alignment
requirements of ATA doesn't this still mean it's only draining up to the
word boundary anyway (so the code is still correct)?

James


-
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] libata: eliminate the home grown dma padding in favour of that provided by the block layer

2008-01-08 Thread Tejun Heo
James Bottomley wrote:
  Also, DMA alignment at
 block layer isn't enough for ATA.  ATA needs drain buffers for ATAPI
 commands with variable length response.  :-(
 
 OK, where is this in the libata code?  The dma_pad size is only 4 bytes,
 so this drain, I assume is only a word long?  Given the word alignment
 requirements of ATA doesn't this still mean it's only draining up to the
 word boundary anyway (so the code is still correct)?

Patch is acked but not merged yet.

http://git.kernel.org/?p=linux/kernel/git/tj/libata-dev.git;a=commit;h=6cd22a0febc74bebe52d58eb22271b8770892a2d

The full function can be read from the following.  It's
ata_sg_setup_extra().

http://git.kernel.org/?p=linux/kernel/git/tj/libata-dev.git;a=blob;f=drivers/ata/libata-core.c;h=d763c072e6cefc724ea24cb68a7adf47b340f054;hb=6cd22a0febc74bebe52d58eb22271b8770892a2d

-- 
tejun
-
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] libata: eliminate the home grown dma padding in favour of that provided by the block layer

2008-01-03 Thread FUJITA Tomonori
On Mon, 31 Dec 2007 15:56:08 -0600
James Bottomley [EMAIL PROTECTED] wrote:

 ATA requires that all DMA transfers begin and end on word boundaries.
 Because of this, a large amount of machinery grew up in ide to adjust
 scatterlists on this basis.  However, as of 2.5, the block layer has a
 dma_alignment variable which ensures both the beginning and length of a
 DMA transfer are aligned on the dma_alignment boundary.  Although the
 block layer does adjust the beginning of the transfer to ensure this
 happens, it doesn't actually adjust the length, it merely makes sure
 that space is allocated for transfers beyond the declared length.  The
 upshot of this is that scatterlists may be padded to any size between
 the actual length and the length adjusted to the dma_alignment safely
 knowing that memory is allocated in this region.

Great!


 diff --git a/include/linux/libata.h b/include/linux/libata.h
 index 124033c..2f40d57 100644
 --- a/include/linux/libata.h
 +++ b/include/linux/libata.h
 @@ -282,7 +282,7 @@ enum {
  
   /* size of buffer to pad xfers ending on unaligned boundaries */
   ATA_DMA_PAD_SZ  = 4,
 - ATA_DMA_PAD_BUF_SZ  = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE,
 + ATA_DMA_PAD_MASK= ATA_DMA_PAD_SZ - 1,
  
   /* ering size */
   ATA_ERING_SIZE  = 32,
 @@ -446,12 +446,9 @@ struct ata_queued_cmd {
   unsigned long   flags;  /* ATA_QCFLAG_xxx */
   unsigned inttag;
   unsigned intn_elem;
 - unsigned intn_iter;
 - unsigned intorig_n_elem;
  
   int dma_dir;
  
 - unsigned intpad_len;
   unsigned intsect_size;
  
   unsigned intnbytes;
 @@ -461,7 +458,6 @@ struct ata_queued_cmd {
   unsigned intcursg_ofs;
  
   struct scatterlist  sgent;
 - struct scatterlist  pad_sgent;
   void*buf_virt;
  
   /* DO NOT iterate over __sg manually, use ata_for_each_sg() */
 @@ -606,9 +602,6 @@ struct ata_port {
   struct ata_prd  *prd;/* our SG list */
   dma_addr_t  prd_dma; /* and its DMA mapping */
  
 - void*pad;   /* array of DMA pad buffers */
 - dma_addr_t  pad_dma;
 -
   struct ata_ioports  ioaddr; /* ATA cmd/ctl/dma register blocks */
  
   u8  ctl;/* cache of ATA control register */
 @@ -1080,24 +1073,15 @@ extern void ata_port_pbar_desc(struct ata_port *ap, 
 int bar, ssize_t offset,
  static inline struct scatterlist *
  ata_qc_first_sg(struct ata_queued_cmd *qc)
  {
 - qc-n_iter = 0;
   if (qc-n_elem)
   return qc-__sg;
 - if (qc-pad_len)
 - return qc-pad_sgent;
   return NULL;
  }
  
  static inline struct scatterlist *
  ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc)
  {
 - if (sg == qc-pad_sgent)
 - return NULL;
 - if (++qc-n_iter  qc-n_elem)
 - return sg_next(sg);
 - if (qc-pad_len)
 - return qc-pad_sgent;
 - return NULL;
 + return sg_next(sg);
  }
  
  #define ata_for_each_sg(sg, qc) \

How about removing ata_qc_first_sg and ata_qc_next_sg completely?

Now we can just replace ata_qc_next_sg with sg_next. qc-__sg seems to
be always initialized to NULL so we can remove ata_qc_first_sg too.


diff --git a/include/linux/libata.h b/include/linux/libata.h
index 4f6404c..2774882 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1054,25 +1054,8 @@ extern void ata_port_pbar_desc(struct ata_port *ap, int 
bar, ssize_t offset,
   const char *name);
 #endif
 
-/*
- * qc helpers
- */
-static inline struct scatterlist *
-ata_qc_first_sg(struct ata_queued_cmd *qc)
-{
-   if (qc-n_elem)
-   return qc-__sg;
-   return NULL;
-}
-
-static inline struct scatterlist *
-ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc)
-{
-   return sg_next(sg);
-}
-
 #define ata_for_each_sg(sg, qc) \
-   for (sg = ata_qc_first_sg(qc); sg; sg = ata_qc_next_sg(sg, qc))
+   for (sg = qc-__sg; sg; sg = sg_next(sg))
 
 static inline unsigned int ata_tag_valid(unsigned int tag)
 {
-
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] libata: eliminate the home grown dma padding in favour of that provided by the block layer

2008-01-03 Thread James Bottomley

On Thu, 2008-01-03 at 16:58 +0900, FUJITA Tomonori wrote:
 On Mon, 31 Dec 2007 15:56:08 -0600
 James Bottomley [EMAIL PROTECTED] wrote:
  @@ -1080,24 +1073,15 @@ extern void ata_port_pbar_desc(struct ata_port *ap, 
  int bar, ssize_t offset,
   static inline struct scatterlist *
   ata_qc_first_sg(struct ata_queued_cmd *qc)
   {
  -   qc-n_iter = 0;
  if (qc-n_elem)
  return qc-__sg;
  -   if (qc-pad_len)
  -   return qc-pad_sgent;
  return NULL;
   }
   
   static inline struct scatterlist *
   ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc)
   {
  -   if (sg == qc-pad_sgent)
  -   return NULL;
  -   if (++qc-n_iter  qc-n_elem)
  -   return sg_next(sg);
  -   if (qc-pad_len)
  -   return qc-pad_sgent;
  -   return NULL;
  +   return sg_next(sg);
   }
   
   #define ata_for_each_sg(sg, qc) \
 
 How about removing ata_qc_first_sg and ata_qc_next_sg completely?
 
 Now we can just replace ata_qc_next_sg with sg_next. qc-__sg seems to
 be always initialized to NULL so we can remove ata_qc_first_sg too.

Sure ... I assumed (without actually looking) that the inlines were
there because they were an API used throughout the drivers.  Actually,
grep tells me they're only used in the ata_for_each_sg macro, so this
patch looks good.

Thanks,

James

 diff --git a/include/linux/libata.h b/include/linux/libata.h
 index 4f6404c..2774882 100644
 --- a/include/linux/libata.h
 +++ b/include/linux/libata.h
 @@ -1054,25 +1054,8 @@ extern void ata_port_pbar_desc(struct ata_port *ap, 
 int bar, ssize_t offset,
  const char *name);
  #endif
  
 -/*
 - * qc helpers
 - */
 -static inline struct scatterlist *
 -ata_qc_first_sg(struct ata_queued_cmd *qc)
 -{
 - if (qc-n_elem)
 - return qc-__sg;
 - return NULL;
 -}
 -
 -static inline struct scatterlist *
 -ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc)
 -{
 - return sg_next(sg);
 -}
 -
  #define ata_for_each_sg(sg, qc) \
 - for (sg = ata_qc_first_sg(qc); sg; sg = ata_qc_next_sg(sg, qc))
 + for (sg = qc-__sg; sg; sg = sg_next(sg))
  
  static inline unsigned int ata_tag_valid(unsigned int tag)
  {
 -
 To unsubscribe from this list: send the line unsubscribe linux-ide in
 the body of a message to [EMAIL PROTECTED]
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

-
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] libata: eliminate the home grown dma padding in favour of that provided by the block layer

2007-12-31 Thread James Bottomley
ATA requires that all DMA transfers begin and end on word boundaries.
Because of this, a large amount of machinery grew up in ide to adjust
scatterlists on this basis.  However, as of 2.5, the block layer has a
dma_alignment variable which ensures both the beginning and length of a
DMA transfer are aligned on the dma_alignment boundary.  Although the
block layer does adjust the beginning of the transfer to ensure this
happens, it doesn't actually adjust the length, it merely makes sure
that space is allocated for transfers beyond the declared length.  The
upshot of this is that scatterlists may be padded to any size between
the actual length and the length adjusted to the dma_alignment safely
knowing that memory is allocated in this region.

Right at the moment, SCSI takes the default dma_aligment which is on a
512 byte boundary.  Note that this aligment only applies to transfers
coming in from user space.  However, since all kernel allocations are
automatically aligned on a minimum of 32 byte boundaries, it is safe to
adjust them in this manner as well.

Signed-off-by: James Bottomley [EMAIL PROTECTED]

---

This also fixes a current panic in libsas with SATAPI devices.  I was
trying to trace a bad interaction between the libata padding and the new
sglist code which was the root cause, and ended up concluding that the
whole libata padding thing was redundant.

In a future improvement, I think we can relax SCSI dma_alignemnt (it's
causing almost every user space command to be copied instead of directly
passed through) and allow devices and transports to build up their own
requirements instead.

James

 drivers/ata/ahci.c|5 -
 drivers/ata/libata-core.c |  126 +++---
 drivers/ata/libata-scsi.c |   18 +-
 drivers/ata/pata_icside.c |8 --
 drivers/ata/sata_fsl.c|   17 -
 drivers/ata/sata_mv.c |5 -
 drivers/ata/sata_nv.c |2 
 drivers/ata/sata_promise.c|2 
 drivers/ata/sata_qstor.c  |2 
 drivers/ata/sata_sil24.c  |5 -
 drivers/scsi/ipr.c|4 -
 drivers/scsi/libsas/sas_ata.c |4 -
 include/linux/libata.h|   35 ---
 13 files changed, 25 insertions(+), 208 deletions(-)

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 54f38c2..4dd318d 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1965,16 +1965,11 @@ static int ahci_port_start(struct ata_port *ap)
struct ahci_port_priv *pp;
void *mem;
dma_addr_t mem_dma;
-   int rc;
 
pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
return -ENOMEM;
 
-   rc = ata_pad_alloc(ap, dev);
-   if (rc)
-   return rc;
-
mem = dmam_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, mem_dma,
  GFP_KERNEL);
if (!mem)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 4753a18..97db82f 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -60,6 +60,8 @@
 #include linux/io.h
 #include scsi/scsi.h
 #include scsi/scsi_cmnd.h
+#include scsi/scsi_device.h
+#include scsi/scsi_dbg.h
 #include scsi/scsi_host.h
 #include linux/libata.h
 #include asm/semaphore.h
@@ -4464,7 +4466,6 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
struct ata_port *ap = qc-ap;
struct scatterlist *sg = qc-__sg;
int dir = qc-dma_dir;
-   void *pad_buf = NULL;
 
WARN_ON(!(qc-flags  ATA_QCFLAG_DMAMAP));
WARN_ON(sg == NULL);
@@ -4474,34 +4475,14 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
 
VPRINTK(unmapping %u sg elements\n, qc-n_elem);
 
-   /* if we padded the buffer out to 32-bit bound, and data
-* xfer direction is from-device, we must copy from the
-* pad buffer back into the supplied buffer
-*/
-   if (qc-pad_len  !(qc-tf.flags  ATA_TFLAG_WRITE))
-   pad_buf = ap-pad + (qc-tag * ATA_DMA_PAD_SZ);
-
if (qc-flags  ATA_QCFLAG_SG) {
if (qc-n_elem)
dma_unmap_sg(ap-dev, sg, qc-n_elem, dir);
-   /* restore last sg */
-   sg_last(sg, qc-orig_n_elem)-length += qc-pad_len;
-   if (pad_buf) {
-   struct scatterlist *psg = qc-pad_sgent;
-   void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
-   memcpy(addr + psg-offset, pad_buf, qc-pad_len);
-   kunmap_atomic(addr, KM_IRQ0);
-   }
} else {
if (qc-n_elem)
dma_unmap_single(ap-dev,
sg_dma_address(sg[0]), sg_dma_len(sg[0]),
dir);
-   /* restore sg */
-   sg-length += qc-pad_len;
-   if (pad_buf)
-   memcpy(qc-buf_virt + sg-length - qc-pad_len,
-  pad_buf, qc-pad_len);

Re: [PATCH] libata: eliminate the home grown dma padding in favour of that provided by the block layer

2007-12-31 Thread Jeff Garzik

James Bottomley wrote:

ATA requires that all DMA transfers begin and end on word boundaries.
Because of this, a large amount of machinery grew up in ide to adjust
scatterlists on this basis.  However, as of 2.5, the block layer has a
dma_alignment variable which ensures both the beginning and length of a
DMA transfer are aligned on the dma_alignment boundary.  Although the
block layer does adjust the beginning of the transfer to ensure this
happens, it doesn't actually adjust the length, it merely makes sure
that space is allocated for transfers beyond the declared length.  The
upshot of this is that scatterlists may be padded to any size between
the actual length and the length adjusted to the dma_alignment safely
knowing that memory is allocated in this region.

Right at the moment, SCSI takes the default dma_aligment which is on a
512 byte boundary.  Note that this aligment only applies to transfers
coming in from user space.  However, since all kernel allocations are
automatically aligned on a minimum of 32 byte boundaries, it is safe to
adjust them in this manner as well.

Signed-off-by: James Bottomley [EMAIL PROTECTED]

---

This also fixes a current panic in libsas with SATAPI devices.  I was
trying to trace a bad interaction between the libata padding and the new
sglist code which was the root cause, and ended up concluding that the
whole libata padding thing was redundant.

In a future improvement, I think we can relax SCSI dma_alignemnt (it's
causing almost every user space command to be copied instead of directly
passed through) and allow devices and transports to build up their own
requirements instead.


Initial read:  ACK, with thanks.  I'll queue this into libata#upstream, 
unless you have other suggestions.


This is definitely the sort of thing that low-level drivers (and their 
helper libs, e.g. libata) should not need to do.


Jeff




-
To unsubscribe from this list: send the line unsubscribe linux-scsi in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html