Message ID | 1288085882-11988-5-git-send-email-amit.salecha@qlogic.com |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
Le mardi 26 octobre 2010 à 02:38 -0700, Amit Kumar Salecha a écrit : > Device requires tx_hw_cosnumer to be 64 byte aligned. > Tx desc size is 64 byte, alloc tx_hw_consumer with tx desc. > > Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com> > --- > drivers/net/qlcnic/qlcnic_ctx.c | 35 +++++++++++++++-------------------- > 1 files changed, 15 insertions(+), 20 deletions(-) > > diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c > index 1cdc05d..21c9c28 100644 > --- a/drivers/net/qlcnic/qlcnic_ctx.c > +++ b/drivers/net/qlcnic/qlcnic_ctx.c > @@ -418,18 +418,9 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) > recv_ctx = &adapter->recv_ctx; > tx_ring = adapter->tx_ring; > > - tx_ring->hw_consumer = (__le32 *)pci_alloc_consistent(pdev, sizeof(u32), > - &tx_ring->hw_cons_phys_addr); > - if (tx_ring->hw_consumer == NULL) { > - dev_err(&pdev->dev, "failed to allocate tx consumer\n"); > - return -ENOMEM; > - } > - *(tx_ring->hw_consumer) = 0; > - > /* cmd desc ring */ > - addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring), > - &tx_ring->phys_addr); > - > + addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring) + > + sizeof(u32), &tx_ring->phys_addr); Wont this use twice memory than before, due to power-of-two allocations ? Allocating 65536 + 4 bytes gives you 131072 bytes. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
> -----Original Message----- > From: Eric Dumazet [mailto:eric.dumazet@gmail.com] > Sent: Tuesday, October 26, 2010 3:25 PM > To: Amit Salecha > Cc: davem@davemloft.net; netdev@vger.kernel.org; Ameen Rahman; Anirban > Chakraborty > Subject: Re: [PATCH] qlcnic: dma address align check > > Le mardi 26 octobre 2010 à 02:38 -0700, Amit Kumar Salecha a écrit : > > Device requires tx_hw_cosnumer to be 64 byte aligned. > > Tx desc size is 64 byte, alloc tx_hw_consumer with tx desc. > > > > Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com> > > --- > > drivers/net/qlcnic/qlcnic_ctx.c | 35 +++++++++++++++-------------- > ------ > > 1 files changed, 15 insertions(+), 20 deletions(-) > > > > diff --git a/drivers/net/qlcnic/qlcnic_ctx.c > b/drivers/net/qlcnic/qlcnic_ctx.c > > index 1cdc05d..21c9c28 100644 > > --- a/drivers/net/qlcnic/qlcnic_ctx.c > > +++ b/drivers/net/qlcnic/qlcnic_ctx.c > > @@ -418,18 +418,9 @@ int qlcnic_alloc_hw_resources(struct > qlcnic_adapter *adapter) > > recv_ctx = &adapter->recv_ctx; > > tx_ring = adapter->tx_ring; > > > > - tx_ring->hw_consumer = (__le32 *)pci_alloc_consistent(pdev, > sizeof(u32), > > - &tx_ring->hw_cons_phys_addr); > > - if (tx_ring->hw_consumer == NULL) { > > - dev_err(&pdev->dev, "failed to allocate tx consumer\n"); > > - return -ENOMEM; > > - } > > - *(tx_ring->hw_consumer) = 0; > > - > > /* cmd desc ring */ > > - addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring), > > - &tx_ring->phys_addr); > > - > > + addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring) + > > + sizeof(u32), &tx_ring->phys_addr); > > Wont this use twice memory than before, due to power-of-two > allocations ? > > Allocating 65536 + 4 bytes gives you 131072 bytes. > Is it ? I am not aware about such calculation. Is pci_alloc_consistent guarantee to give PAGE align dma address ? -Amit
Le mardi 26 octobre 2010 à 05:04 -0500, Amit Salecha a écrit : > Is it ? I am not aware about such calculation. Yes it is > Is pci_alloc_consistent guarantee to give PAGE align dma address ? I believe so By the way, you should use dma_alloc_coherent() instead of pci_alloc_consistent() so that you can use GFP_KERNEL allocations instead of GFP_ATOMIC, it might help in low memory conditions (if you dont hold a spinlock at this point) If TX_DESC_RINGSIZE(tx_ring) is not a power of two, then yes you could probably add 64 bytes and avoid allocating a full page only for the u32 field ;) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
> > Is pci_alloc_consistent guarantee to give PAGE align dma address ? > > I believe so > > By the way, you should use dma_alloc_coherent() instead of > pci_alloc_consistent() so that you can use GFP_KERNEL allocations > instead of GFP_ATOMIC, it might help in low memory conditions (if you > dont hold a spinlock at this point) > > > If TX_DESC_RINGSIZE(tx_ring) is not a power of two, then yes you could > probably add 64 bytes and avoid allocating a full page only for the u32 > field ;) > > TX_DESC_RINGSIZE is power of two. If pci_alloc_consistent guarantee to give PAGE align dma address, then this patch is not required. >
diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index 1cdc05d..21c9c28 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -418,18 +418,9 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) recv_ctx = &adapter->recv_ctx; tx_ring = adapter->tx_ring; - tx_ring->hw_consumer = (__le32 *)pci_alloc_consistent(pdev, sizeof(u32), - &tx_ring->hw_cons_phys_addr); - if (tx_ring->hw_consumer == NULL) { - dev_err(&pdev->dev, "failed to allocate tx consumer\n"); - return -ENOMEM; - } - *(tx_ring->hw_consumer) = 0; - /* cmd desc ring */ - addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring), - &tx_ring->phys_addr); - + addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring) + + sizeof(u32), &tx_ring->phys_addr); if (addr == NULL) { dev_err(&pdev->dev, "failed to allocate tx desc ring\n"); err = -ENOMEM; @@ -437,6 +428,17 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) } tx_ring->desc_head = (struct cmd_desc_type0 *)addr; + tx_ring->hw_consumer = (__le32 *)(((char *)addr) + + TX_DESC_RINGSIZE(tx_ring)); + tx_ring->hw_cons_phys_addr = (dma_addr_t)(((char *)tx_ring->phys_addr) + + TX_DESC_RINGSIZE(tx_ring)); + if (tx_ring->hw_cons_phys_addr & 0x3F) { + dev_err(&pdev->dev, "Device requires 64 byte aligned dma addr" + ". dma_addr=%p\n", (void *)tx_ring->hw_cons_phys_addr); + err = -ENOMEM; + goto err_out_free; + } + *(tx_ring->hw_consumer) = 0; for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; @@ -516,19 +518,12 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter) recv_ctx = &adapter->recv_ctx; tx_ring = adapter->tx_ring; - if (tx_ring->hw_consumer != NULL) { - pci_free_consistent(adapter->pdev, - sizeof(u32), - tx_ring->hw_consumer, - tx_ring->hw_cons_phys_addr); - tx_ring->hw_consumer = NULL; - } - if (tx_ring->desc_head != NULL) { pci_free_consistent(adapter->pdev, - TX_DESC_RINGSIZE(tx_ring), + TX_DESC_RINGSIZE(tx_ring) + sizeof(u32), tx_ring->desc_head, tx_ring->phys_addr); tx_ring->desc_head = NULL; + tx_ring->hw_consumer = NULL; } for (ring = 0; ring < adapter->max_rds_rings; ring++) {
Device requires tx_hw_cosnumer to be 64 byte aligned. Tx desc size is 64 byte, alloc tx_hw_consumer with tx desc. Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com> --- drivers/net/qlcnic/qlcnic_ctx.c | 35 +++++++++++++++-------------------- 1 files changed, 15 insertions(+), 20 deletions(-)