* [PATCH v2 0/3] net: ti: netcp: restore get/set_pad_info() functionality
@ 2016-02-19 17:58 Murali Karicheri
2016-02-19 17:58 ` [PATCH v2 1/3] " Murali Karicheri
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: Murali Karicheri @ 2016-02-19 17:58 UTC (permalink / raw)
To: linux-kernel, netdev, davem, arnd
This series fixes a regression and add some improvements for the ease
of maintainance. Incorporated comments against v1.
Changelogs:
v2 : combined 2-3 into one patch as this involves a header change
fixed a parse warning in 3/4 per comment from Arnd.
Removed Sign-off from Arnd against 1/4
added comments in 3/3 to alert on the usage of sw data per review
comments
v1 : added 2-4 to accomodate feedback received from review
v0 : initial version to fix the regression (From Grygorii)
Murali Karicheri (3):
net: ti: netcp: restore get/set_pad_info() functionality
soc: ti: knav_dma: rename pad in struct knav_dma_desc to sw_data
net: netcp: rework the code for get/set sw_data in dma desc
drivers/net/ethernet/ti/netcp_core.c | 105 ++++++++++++++++++++---------------
include/linux/soc/ti/knav_dma.h | 4 +-
2 files changed, 64 insertions(+), 45 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 1/3] net: ti: netcp: restore get/set_pad_info() functionality
2016-02-19 17:58 [PATCH v2 0/3] net: ti: netcp: restore get/set_pad_info() functionality Murali Karicheri
@ 2016-02-19 17:58 ` Murali Karicheri
2016-02-19 20:56 ` Arnd Bergmann
2016-02-19 17:58 ` [PATCH v2 2/3] soc: ti: knav_dma: rename pad in struct knav_dma_desc to sw_data Murali Karicheri
` (2 subsequent siblings)
3 siblings, 1 reply; 11+ messages in thread
From: Murali Karicheri @ 2016-02-19 17:58 UTC (permalink / raw)
To: linux-kernel, netdev, davem, arnd
The commit 899077791403 ("netcp: try to reduce type confusion in
descriptors") introduces a regression in Kernel 4.5-rc1 and it breaks
get/set_pad_info() functionality.
The TI NETCP driver uses pad0 and pad1 fields of knav_dma_desc to
store DMA/MEM buffer pointer and buffer size respectively. And in both
cases for Keystone 2 the pointer type size is 32 bit regardless of
LAPE enabled or not, because CONFIG_ARCH_DMA_ADDR_T_64BIT originally
is not expected to be defined.
Unfortunately, above commit changed buffer's pointers save/restore
code (get/set_pad_info()) and added intermediate conversation to u64
which works incorrectly on 32bit Keystone 2 and causes TI NETCP driver
crash in RX/TX path due to "Unable to handle kernel NULL pointer"
exception. This issue was reported and discussed in [1].
Hence, fix it by partially reverting above commit and restoring
get/set_pad_info() functionality as it was before.
[1] https://www.mail-archive.com/netdev@vger.kernel.org/msg95361.html
Cc: Wingman Kwok <w-kwok2@ti.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
CC: David Laight <David.Laight@ACULAB.COM>
CC: Arnd Bergmann <arnd@arndb.de>
Reported-by: Franklin S Cooper Jr <fcooper@ti.com>
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
drivers/net/ethernet/ti/netcp_core.c | 59 +++++++++++-------------------------
1 file changed, 18 insertions(+), 41 deletions(-)
diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c
index c61d66d..0b26e52 100644
--- a/drivers/net/ethernet/ti/netcp_core.c
+++ b/drivers/net/ethernet/ti/netcp_core.c
@@ -117,20 +117,10 @@ static void get_pkt_info(dma_addr_t *buff, u32 *buff_len, dma_addr_t *ndesc,
*ndesc = le32_to_cpu(desc->next_desc);
}
-static void get_pad_info(u32 *pad0, u32 *pad1, u32 *pad2, struct knav_dma_desc *desc)
+static void get_pad_info(u32 *pad0, u32 *pad1, struct knav_dma_desc *desc)
{
*pad0 = le32_to_cpu(desc->pad[0]);
*pad1 = le32_to_cpu(desc->pad[1]);
- *pad2 = le32_to_cpu(desc->pad[2]);
-}
-
-static void get_pad_ptr(void **padptr, struct knav_dma_desc *desc)
-{
- u64 pad64;
-
- pad64 = le32_to_cpu(desc->pad[0]) +
- ((u64)le32_to_cpu(desc->pad[1]) << 32);
- *padptr = (void *)(uintptr_t)pad64;
}
static void get_org_pkt_info(dma_addr_t *buff, u32 *buff_len,
@@ -163,11 +153,10 @@ static void set_desc_info(u32 desc_info, u32 pkt_info,
desc->packet_info = cpu_to_le32(pkt_info);
}
-static void set_pad_info(u32 pad0, u32 pad1, u32 pad2, struct knav_dma_desc *desc)
+static void set_pad_info(u32 pad0, u32 pad1, struct knav_dma_desc *desc)
{
desc->pad[0] = cpu_to_le32(pad0);
desc->pad[1] = cpu_to_le32(pad1);
- desc->pad[2] = cpu_to_le32(pad1);
}
static void set_org_pkt_info(dma_addr_t buff, u32 buff_len,
@@ -581,7 +570,6 @@ static void netcp_free_rx_desc_chain(struct netcp_intf *netcp,
dma_addr_t dma_desc, dma_buf;
unsigned int buf_len, dma_sz = sizeof(*ndesc);
void *buf_ptr;
- u32 pad[2];
u32 tmp;
get_words(&dma_desc, 1, &desc->next_desc);
@@ -593,14 +581,12 @@ static void netcp_free_rx_desc_chain(struct netcp_intf *netcp,
break;
}
get_pkt_info(&dma_buf, &tmp, &dma_desc, ndesc);
- get_pad_ptr(&buf_ptr, ndesc);
+ get_pad_info((u32 *)&buf_ptr, &buf_len, ndesc);
dma_unmap_page(netcp->dev, dma_buf, PAGE_SIZE, DMA_FROM_DEVICE);
__free_page(buf_ptr);
knav_pool_desc_put(netcp->rx_pool, desc);
}
-
- get_pad_info(&pad[0], &pad[1], &buf_len, desc);
- buf_ptr = (void *)(uintptr_t)(pad[0] + ((u64)pad[1] << 32));
+ get_pad_info((u32 *)&buf_ptr, &buf_len, desc);
if (buf_ptr)
netcp_frag_free(buf_len <= PAGE_SIZE, buf_ptr);
@@ -639,8 +625,8 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
dma_addr_t dma_desc, dma_buff;
struct netcp_packet p_info;
struct sk_buff *skb;
- u32 pad[2];
void *org_buf_ptr;
+ u32 tmp;
dma_desc = knav_queue_pop(netcp->rx_queue, &dma_sz);
if (!dma_desc)
@@ -653,8 +639,7 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
}
get_pkt_info(&dma_buff, &buf_len, &dma_desc, desc);
- get_pad_info(&pad[0], &pad[1], &org_buf_len, desc);
- org_buf_ptr = (void *)(uintptr_t)(pad[0] + ((u64)pad[1] << 32));
+ get_pad_info((u32 *)&org_buf_ptr, &org_buf_len, desc);
if (unlikely(!org_buf_ptr)) {
dev_err(netcp->ndev_dev, "NULL bufptr in desc\n");
@@ -679,7 +664,6 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
/* Fill in the page fragment list */
while (dma_desc) {
struct page *page;
- void *ptr;
ndesc = knav_pool_desc_unmap(netcp->rx_pool, dma_desc, dma_sz);
if (unlikely(!ndesc)) {
@@ -688,8 +672,7 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
}
get_pkt_info(&dma_buff, &buf_len, &dma_desc, ndesc);
- get_pad_ptr(&ptr, ndesc);
- page = ptr;
+ get_pad_info((u32 *)&page, &tmp, ndesc);
if (likely(dma_buff && buf_len && page)) {
dma_unmap_page(netcp->dev, dma_buff, PAGE_SIZE,
@@ -767,6 +750,7 @@ static void netcp_free_rx_buf(struct netcp_intf *netcp, int fdq)
unsigned int buf_len, dma_sz;
dma_addr_t dma;
void *buf_ptr;
+ u32 tmp;
/* Allocate descriptor */
while ((dma = knav_queue_pop(netcp->rx_fdq[fdq], &dma_sz))) {
@@ -777,7 +761,7 @@ static void netcp_free_rx_buf(struct netcp_intf *netcp, int fdq)
}
get_org_pkt_info(&dma, &buf_len, desc);
- get_pad_ptr(&buf_ptr, desc);
+ get_pad_info((u32 *)&buf_ptr, &tmp, desc);
if (unlikely(!dma)) {
dev_err(netcp->ndev_dev, "NULL orig_buff in desc\n");
@@ -829,7 +813,7 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
struct page *page;
dma_addr_t dma;
void *bufptr;
- u32 pad[3];
+ u32 pad[2];
/* Allocate descriptor */
hwdesc = knav_pool_desc_get(netcp->rx_pool);
@@ -846,7 +830,7 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
bufptr = netdev_alloc_frag(primary_buf_len);
- pad[2] = primary_buf_len;
+ pad[1] = primary_buf_len;
if (unlikely(!bufptr)) {
dev_warn_ratelimited(netcp->ndev_dev,
@@ -858,9 +842,7 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
if (unlikely(dma_mapping_error(netcp->dev, dma)))
goto fail;
- pad[0] = lower_32_bits((uintptr_t)bufptr);
- pad[1] = upper_32_bits((uintptr_t)bufptr);
-
+ pad[0] = (u32)bufptr;
} else {
/* Allocate a secondary receive queue entry */
page = alloc_page(GFP_ATOMIC | GFP_DMA | __GFP_COLD);
@@ -870,9 +852,8 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
}
buf_len = PAGE_SIZE;
dma = dma_map_page(netcp->dev, page, 0, buf_len, DMA_TO_DEVICE);
- pad[0] = lower_32_bits(dma);
- pad[1] = upper_32_bits(dma);
- pad[2] = 0;
+ pad[0] = (u32)page;
+ pad[1] = 0;
}
desc_info = KNAV_DMA_DESC_PS_INFO_IN_DESC;
@@ -882,7 +863,7 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
pkt_info |= (netcp->rx_queue_id & KNAV_DMA_DESC_RETQ_MASK) <<
KNAV_DMA_DESC_RETQ_SHIFT;
set_org_pkt_info(dma, buf_len, hwdesc);
- set_pad_info(pad[0], pad[1], pad[2], hwdesc);
+ set_pad_info(pad[0], pad[1], hwdesc);
set_desc_info(desc_info, pkt_info, hwdesc);
/* Push to FDQs */
@@ -971,11 +952,11 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp,
unsigned int budget)
{
struct knav_dma_desc *desc;
- void *ptr;
struct sk_buff *skb;
unsigned int dma_sz;
dma_addr_t dma;
int pkts = 0;
+ u32 tmp;
while (budget--) {
dma = knav_queue_pop(netcp->tx_compl_q, &dma_sz);
@@ -988,8 +969,7 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp,
continue;
}
- get_pad_ptr(&ptr, desc);
- skb = ptr;
+ get_pad_info((u32 *)&skb, &tmp, desc);
netcp_free_tx_desc_chain(netcp, desc, dma_sz);
if (!skb) {
dev_err(netcp->ndev_dev, "No skb in Tx desc\n");
@@ -1194,10 +1174,7 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp,
}
set_words(&tmp, 1, &desc->packet_info);
- tmp = lower_32_bits((uintptr_t)&skb);
- set_words(&tmp, 1, &desc->pad[0]);
- tmp = upper_32_bits((uintptr_t)&skb);
- set_words(&tmp, 1, &desc->pad[1]);
+ set_words((u32 *)&skb, 1, &desc->pad[0]);
if (tx_pipe->flags & SWITCH_TO_PORT_IN_TAGINFO) {
tmp = tx_pipe->switch_to_port;
--
1.9.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 2/3] soc: ti: knav_dma: rename pad in struct knav_dma_desc to sw_data
2016-02-19 17:58 [PATCH v2 0/3] net: ti: netcp: restore get/set_pad_info() functionality Murali Karicheri
2016-02-19 17:58 ` [PATCH v2 1/3] " Murali Karicheri
@ 2016-02-19 17:58 ` Murali Karicheri
2016-02-19 20:55 ` Arnd Bergmann
2016-02-19 17:58 ` [PATCH v2 3/3] net: netcp: rework the code for get/set sw_data in dma desc Murali Karicheri
2016-02-22 3:02 ` [PATCH v2 0/3] net: ti: netcp: restore get/set_pad_info() functionality David Miller
3 siblings, 1 reply; 11+ messages in thread
From: Murali Karicheri @ 2016-02-19 17:58 UTC (permalink / raw)
To: linux-kernel, netdev, davem, arnd
Rename the pad to sw_data as per description of this field in the hardware
spec(refer sprugr9 from www.ti.com). Latest version of the document is
at http://www.ti.com/lit/ug/sprugr9h/sprugr9h.pdf and section 3.1
Host Packet Descriptor describes this field.
Define and use a constant for the size of sw_data field similar to
other fields in the struct for desc and document the sw_data field
in the header. As the sw_data is not touched by hw, it's type can be
changed to u32.
Rename the helpers to match with the updated dma desc field sw_data.
Cc: Wingman Kwok <w-kwok2@ti.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Grygorii Strashko <grygorii.strashko@ti.com>
CC: David Laight <David.Laight@ACULAB.COM>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
drivers/net/ethernet/ti/netcp_core.c | 40 +++++++++++++++++++-----------------
include/linux/soc/ti/knav_dma.h | 4 +++-
2 files changed, 24 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c
index 0b26e52..84bab29 100644
--- a/drivers/net/ethernet/ti/netcp_core.c
+++ b/drivers/net/ethernet/ti/netcp_core.c
@@ -117,10 +117,11 @@ static void get_pkt_info(dma_addr_t *buff, u32 *buff_len, dma_addr_t *ndesc,
*ndesc = le32_to_cpu(desc->next_desc);
}
-static void get_pad_info(u32 *pad0, u32 *pad1, struct knav_dma_desc *desc)
+static void get_sw_data(u32 *data0, u32 *data1, struct knav_dma_desc *desc)
{
- *pad0 = le32_to_cpu(desc->pad[0]);
- *pad1 = le32_to_cpu(desc->pad[1]);
+ /* No Endian conversion needed as this data is untouched by hw */
+ *data0 = desc->sw_data[0];
+ *data1 = desc->sw_data[1];
}
static void get_org_pkt_info(dma_addr_t *buff, u32 *buff_len,
@@ -153,10 +154,11 @@ static void set_desc_info(u32 desc_info, u32 pkt_info,
desc->packet_info = cpu_to_le32(pkt_info);
}
-static void set_pad_info(u32 pad0, u32 pad1, struct knav_dma_desc *desc)
+static void set_sw_data(u32 data0, u32 data1, struct knav_dma_desc *desc)
{
- desc->pad[0] = cpu_to_le32(pad0);
- desc->pad[1] = cpu_to_le32(pad1);
+ /* No Endian conversion needed as this data is untouched by hw */
+ desc->sw_data[0] = data0;
+ desc->sw_data[1] = data1;
}
static void set_org_pkt_info(dma_addr_t buff, u32 buff_len,
@@ -581,12 +583,12 @@ static void netcp_free_rx_desc_chain(struct netcp_intf *netcp,
break;
}
get_pkt_info(&dma_buf, &tmp, &dma_desc, ndesc);
- get_pad_info((u32 *)&buf_ptr, &buf_len, ndesc);
+ get_sw_data((u32 *)&buf_ptr, &buf_len, ndesc);
dma_unmap_page(netcp->dev, dma_buf, PAGE_SIZE, DMA_FROM_DEVICE);
__free_page(buf_ptr);
knav_pool_desc_put(netcp->rx_pool, desc);
}
- get_pad_info((u32 *)&buf_ptr, &buf_len, desc);
+ get_sw_data((u32 *)&buf_ptr, &buf_len, desc);
if (buf_ptr)
netcp_frag_free(buf_len <= PAGE_SIZE, buf_ptr);
@@ -639,7 +641,7 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
}
get_pkt_info(&dma_buff, &buf_len, &dma_desc, desc);
- get_pad_info((u32 *)&org_buf_ptr, &org_buf_len, desc);
+ get_sw_data((u32 *)&org_buf_ptr, &org_buf_len, desc);
if (unlikely(!org_buf_ptr)) {
dev_err(netcp->ndev_dev, "NULL bufptr in desc\n");
@@ -672,7 +674,7 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
}
get_pkt_info(&dma_buff, &buf_len, &dma_desc, ndesc);
- get_pad_info((u32 *)&page, &tmp, ndesc);
+ get_sw_data((u32 *)&page, &tmp, ndesc);
if (likely(dma_buff && buf_len && page)) {
dma_unmap_page(netcp->dev, dma_buff, PAGE_SIZE,
@@ -761,7 +763,7 @@ static void netcp_free_rx_buf(struct netcp_intf *netcp, int fdq)
}
get_org_pkt_info(&dma, &buf_len, desc);
- get_pad_info((u32 *)&buf_ptr, &tmp, desc);
+ get_sw_data((u32 *)&buf_ptr, &tmp, desc);
if (unlikely(!dma)) {
dev_err(netcp->ndev_dev, "NULL orig_buff in desc\n");
@@ -813,7 +815,7 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
struct page *page;
dma_addr_t dma;
void *bufptr;
- u32 pad[2];
+ u32 sw_data[2];
/* Allocate descriptor */
hwdesc = knav_pool_desc_get(netcp->rx_pool);
@@ -830,7 +832,7 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
bufptr = netdev_alloc_frag(primary_buf_len);
- pad[1] = primary_buf_len;
+ sw_data[1] = primary_buf_len;
if (unlikely(!bufptr)) {
dev_warn_ratelimited(netcp->ndev_dev,
@@ -842,7 +844,7 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
if (unlikely(dma_mapping_error(netcp->dev, dma)))
goto fail;
- pad[0] = (u32)bufptr;
+ sw_data[0] = (u32)bufptr;
} else {
/* Allocate a secondary receive queue entry */
page = alloc_page(GFP_ATOMIC | GFP_DMA | __GFP_COLD);
@@ -852,8 +854,8 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
}
buf_len = PAGE_SIZE;
dma = dma_map_page(netcp->dev, page, 0, buf_len, DMA_TO_DEVICE);
- pad[0] = (u32)page;
- pad[1] = 0;
+ sw_data[0] = (u32)page;
+ sw_data[1] = 0;
}
desc_info = KNAV_DMA_DESC_PS_INFO_IN_DESC;
@@ -863,7 +865,7 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
pkt_info |= (netcp->rx_queue_id & KNAV_DMA_DESC_RETQ_MASK) <<
KNAV_DMA_DESC_RETQ_SHIFT;
set_org_pkt_info(dma, buf_len, hwdesc);
- set_pad_info(pad[0], pad[1], hwdesc);
+ set_sw_data(sw_data[0], sw_data[1], hwdesc);
set_desc_info(desc_info, pkt_info, hwdesc);
/* Push to FDQs */
@@ -969,7 +971,7 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp,
continue;
}
- get_pad_info((u32 *)&skb, &tmp, desc);
+ get_sw_data((u32 *)&skb, &tmp, desc);
netcp_free_tx_desc_chain(netcp, desc, dma_sz);
if (!skb) {
dev_err(netcp->ndev_dev, "No skb in Tx desc\n");
@@ -1174,7 +1176,7 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp,
}
set_words(&tmp, 1, &desc->packet_info);
- set_words((u32 *)&skb, 1, &desc->pad[0]);
+ set_sw_data((u32)skb, 0, desc);
if (tx_pipe->flags & SWITCH_TO_PORT_IN_TAGINFO) {
tmp = tx_pipe->switch_to_port;
diff --git a/include/linux/soc/ti/knav_dma.h b/include/linux/soc/ti/knav_dma.h
index 343c13a..35cb926 100644
--- a/include/linux/soc/ti/knav_dma.h
+++ b/include/linux/soc/ti/knav_dma.h
@@ -44,6 +44,7 @@
#define KNAV_DMA_NUM_EPIB_WORDS 4
#define KNAV_DMA_NUM_PS_WORDS 16
+#define KNAV_DMA_NUM_SW_DATA_WORDS 4
#define KNAV_DMA_FDQ_PER_CHAN 4
/* Tx channel scheduling priority */
@@ -142,6 +143,7 @@ struct knav_dma_cfg {
* @orig_buff: buff pointer since 'buff' can be overwritten
* @epib: Extended packet info block
* @psdata: Protocol specific
+ * @sw_data: Software private data not touched by h/w
*/
struct knav_dma_desc {
__le32 desc_info;
@@ -154,7 +156,7 @@ struct knav_dma_desc {
__le32 orig_buff;
__le32 epib[KNAV_DMA_NUM_EPIB_WORDS];
__le32 psdata[KNAV_DMA_NUM_PS_WORDS];
- __le32 pad[4];
+ u32 sw_data[KNAV_DMA_NUM_SW_DATA_WORDS];
} ____cacheline_aligned;
#if IS_ENABLED(CONFIG_KEYSTONE_NAVIGATOR_DMA)
--
1.9.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 3/3] net: netcp: rework the code for get/set sw_data in dma desc
2016-02-19 17:58 [PATCH v2 0/3] net: ti: netcp: restore get/set_pad_info() functionality Murali Karicheri
2016-02-19 17:58 ` [PATCH v2 1/3] " Murali Karicheri
2016-02-19 17:58 ` [PATCH v2 2/3] soc: ti: knav_dma: rename pad in struct knav_dma_desc to sw_data Murali Karicheri
@ 2016-02-19 17:58 ` Murali Karicheri
2016-02-19 20:55 ` Arnd Bergmann
2016-02-22 3:02 ` [PATCH v2 0/3] net: ti: netcp: restore get/set_pad_info() functionality David Miller
3 siblings, 1 reply; 11+ messages in thread
From: Murali Karicheri @ 2016-02-19 17:58 UTC (permalink / raw)
To: linux-kernel, netdev, davem, arnd
SW data field in descriptor can be used by software to hold private
data for the driver. As there are 4 words available for this purpose,
use separate macros to place it or retrieve the same to/from
descriptors. Also do type cast of data types accordingly.
Cc: Wingman Kwok <w-kwok2@ti.com>
Cc: Mugunthan V N <mugunthanvnm@ti.com>
CC: Arnd Bergmann <arnd@arndb.de>
CC: Grygorii Strashko <grygorii.strashko@ti.com>
CC: David Laight <David.Laight@ACULAB.COM>
Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
---
drivers/net/ethernet/ti/netcp_core.c | 72 +++++++++++++++++++++++++++---------
1 file changed, 55 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c
index 84bab29..029841f 100644
--- a/drivers/net/ethernet/ti/netcp_core.c
+++ b/drivers/net/ethernet/ti/netcp_core.c
@@ -117,13 +117,18 @@ static void get_pkt_info(dma_addr_t *buff, u32 *buff_len, dma_addr_t *ndesc,
*ndesc = le32_to_cpu(desc->next_desc);
}
-static void get_sw_data(u32 *data0, u32 *data1, struct knav_dma_desc *desc)
+static u32 get_sw_data(int index, struct knav_dma_desc *desc)
{
/* No Endian conversion needed as this data is untouched by hw */
- *data0 = desc->sw_data[0];
- *data1 = desc->sw_data[1];
+ return desc->sw_data[index];
}
+/* use these macros to get sw data */
+#define GET_SW_DATA0(desc) get_sw_data(0, desc)
+#define GET_SW_DATA1(desc) get_sw_data(1, desc)
+#define GET_SW_DATA2(desc) get_sw_data(2, desc)
+#define GET_SW_DATA3(desc) get_sw_data(3, desc)
+
static void get_org_pkt_info(dma_addr_t *buff, u32 *buff_len,
struct knav_dma_desc *desc)
{
@@ -154,13 +159,18 @@ static void set_desc_info(u32 desc_info, u32 pkt_info,
desc->packet_info = cpu_to_le32(pkt_info);
}
-static void set_sw_data(u32 data0, u32 data1, struct knav_dma_desc *desc)
+static void set_sw_data(int index, u32 data, struct knav_dma_desc *desc)
{
/* No Endian conversion needed as this data is untouched by hw */
- desc->sw_data[0] = data0;
- desc->sw_data[1] = data1;
+ desc->sw_data[index] = data;
}
+/* use these macros to set sw data */
+#define SET_SW_DATA0(data, desc) set_sw_data(0, data, desc)
+#define SET_SW_DATA1(data, desc) set_sw_data(1, data, desc)
+#define SET_SW_DATA2(data, desc) set_sw_data(2, data, desc)
+#define SET_SW_DATA3(data, desc) set_sw_data(3, data, desc)
+
static void set_org_pkt_info(dma_addr_t buff, u32 buff_len,
struct knav_dma_desc *desc)
{
@@ -583,12 +593,20 @@ static void netcp_free_rx_desc_chain(struct netcp_intf *netcp,
break;
}
get_pkt_info(&dma_buf, &tmp, &dma_desc, ndesc);
- get_sw_data((u32 *)&buf_ptr, &buf_len, ndesc);
+ /* warning!!!! We are retrieving the virtual ptr in the sw_data
+ * field as a 32bit value. Will not work on 64bit machines
+ */
+ buf_ptr = (void *)GET_SW_DATA0(ndesc);
+ buf_len = (int)GET_SW_DATA1(desc);
dma_unmap_page(netcp->dev, dma_buf, PAGE_SIZE, DMA_FROM_DEVICE);
__free_page(buf_ptr);
knav_pool_desc_put(netcp->rx_pool, desc);
}
- get_sw_data((u32 *)&buf_ptr, &buf_len, desc);
+ /* warning!!!! We are retrieving the virtual ptr in the sw_data
+ * field as a 32bit value. Will not work on 64bit machines
+ */
+ buf_ptr = (void *)GET_SW_DATA0(desc);
+ buf_len = (int)GET_SW_DATA1(desc);
if (buf_ptr)
netcp_frag_free(buf_len <= PAGE_SIZE, buf_ptr);
@@ -628,7 +646,6 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
struct netcp_packet p_info;
struct sk_buff *skb;
void *org_buf_ptr;
- u32 tmp;
dma_desc = knav_queue_pop(netcp->rx_queue, &dma_sz);
if (!dma_desc)
@@ -641,7 +658,11 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
}
get_pkt_info(&dma_buff, &buf_len, &dma_desc, desc);
- get_sw_data((u32 *)&org_buf_ptr, &org_buf_len, desc);
+ /* warning!!!! We are retrieving the virtual ptr in the sw_data
+ * field as a 32bit value. Will not work on 64bit machines
+ */
+ org_buf_ptr = (void *)GET_SW_DATA0(desc);
+ org_buf_len = (int)GET_SW_DATA1(desc);
if (unlikely(!org_buf_ptr)) {
dev_err(netcp->ndev_dev, "NULL bufptr in desc\n");
@@ -674,7 +695,10 @@ static int netcp_process_one_rx_packet(struct netcp_intf *netcp)
}
get_pkt_info(&dma_buff, &buf_len, &dma_desc, ndesc);
- get_sw_data((u32 *)&page, &tmp, ndesc);
+ /* warning!!!! We are retrieving the virtual ptr in the sw_data
+ * field as a 32bit value. Will not work on 64bit machines
+ */
+ page = (struct page *)GET_SW_DATA0(desc);
if (likely(dma_buff && buf_len && page)) {
dma_unmap_page(netcp->dev, dma_buff, PAGE_SIZE,
@@ -752,7 +776,6 @@ static void netcp_free_rx_buf(struct netcp_intf *netcp, int fdq)
unsigned int buf_len, dma_sz;
dma_addr_t dma;
void *buf_ptr;
- u32 tmp;
/* Allocate descriptor */
while ((dma = knav_queue_pop(netcp->rx_fdq[fdq], &dma_sz))) {
@@ -763,7 +786,10 @@ static void netcp_free_rx_buf(struct netcp_intf *netcp, int fdq)
}
get_org_pkt_info(&dma, &buf_len, desc);
- get_sw_data((u32 *)&buf_ptr, &tmp, desc);
+ /* warning!!!! We are retrieving the virtual ptr in the sw_data
+ * field as a 32bit value. Will not work on 64bit machines
+ */
+ buf_ptr = (void *)GET_SW_DATA0(desc);
if (unlikely(!dma)) {
dev_err(netcp->ndev_dev, "NULL orig_buff in desc\n");
@@ -844,6 +870,9 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
if (unlikely(dma_mapping_error(netcp->dev, dma)))
goto fail;
+ /* warning!!!! We are saving the virtual ptr in the sw_data
+ * field as a 32bit value. Will not work on 64bit machines
+ */
sw_data[0] = (u32)bufptr;
} else {
/* Allocate a secondary receive queue entry */
@@ -854,6 +883,9 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
}
buf_len = PAGE_SIZE;
dma = dma_map_page(netcp->dev, page, 0, buf_len, DMA_TO_DEVICE);
+ /* warning!!!! We are saving the virtual ptr in the sw_data
+ * field as a 32bit value. Will not work on 64bit machines
+ */
sw_data[0] = (u32)page;
sw_data[1] = 0;
}
@@ -865,7 +897,8 @@ static int netcp_allocate_rx_buf(struct netcp_intf *netcp, int fdq)
pkt_info |= (netcp->rx_queue_id & KNAV_DMA_DESC_RETQ_MASK) <<
KNAV_DMA_DESC_RETQ_SHIFT;
set_org_pkt_info(dma, buf_len, hwdesc);
- set_sw_data(sw_data[0], sw_data[1], hwdesc);
+ SET_SW_DATA0(sw_data[0], hwdesc);
+ SET_SW_DATA1(sw_data[1], hwdesc);
set_desc_info(desc_info, pkt_info, hwdesc);
/* Push to FDQs */
@@ -958,7 +991,6 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp,
unsigned int dma_sz;
dma_addr_t dma;
int pkts = 0;
- u32 tmp;
while (budget--) {
dma = knav_queue_pop(netcp->tx_compl_q, &dma_sz);
@@ -971,7 +1003,10 @@ static int netcp_process_tx_compl_packets(struct netcp_intf *netcp,
continue;
}
- get_sw_data((u32 *)&skb, &tmp, desc);
+ /* warning!!!! We are retrieving the virtual ptr in the sw_data
+ * field as a 32bit value. Will not work on 64bit machines
+ */
+ skb = (struct sk_buff *)GET_SW_DATA0(desc);
netcp_free_tx_desc_chain(netcp, desc, dma_sz);
if (!skb) {
dev_err(netcp->ndev_dev, "No skb in Tx desc\n");
@@ -1176,7 +1211,10 @@ static int netcp_tx_submit_skb(struct netcp_intf *netcp,
}
set_words(&tmp, 1, &desc->packet_info);
- set_sw_data((u32)skb, 0, desc);
+ /* warning!!!! We are saving the virtual ptr in the sw_data
+ * field as a 32bit value. Will not work on 64bit machines
+ */
+ SET_SW_DATA0((u32)skb, desc);
if (tx_pipe->flags & SWITCH_TO_PORT_IN_TAGINFO) {
tmp = tx_pipe->switch_to_port;
--
1.9.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 3/3] net: netcp: rework the code for get/set sw_data in dma desc
2016-02-19 17:58 ` [PATCH v2 3/3] net: netcp: rework the code for get/set sw_data in dma desc Murali Karicheri
@ 2016-02-19 20:55 ` Arnd Bergmann
2016-02-19 22:21 ` Murali Karicheri
0 siblings, 1 reply; 11+ messages in thread
From: Arnd Bergmann @ 2016-02-19 20:55 UTC (permalink / raw)
To: Murali Karicheri; +Cc: linux-kernel, netdev, davem
On Friday 19 February 2016 12:58:44 Murali Karicheri wrote:
> SW data field in descriptor can be used by software to hold private
> data for the driver. As there are 4 words available for this purpose,
> use separate macros to place it or retrieve the same to/from
> descriptors. Also do type cast of data types accordingly.
>
> Cc: Wingman Kwok <w-kwok2@ti.com>
> Cc: Mugunthan V N <mugunthanvnm@ti.com>
> CC: Arnd Bergmann <arnd@arndb.de>
> CC: Grygorii Strashko <grygorii.strashko@ti.com>
> CC: David Laight <David.Laight@ACULAB.COM>
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
Looks ok in principle.
Acked-by: Arnd Bergmann <arnd@arndb.de>
> get_pkt_info(&dma_buf, &tmp, &dma_desc, ndesc);
> - get_sw_data((u32 *)&buf_ptr, &buf_len, ndesc);
> + /* warning!!!! We are retrieving the virtual ptr in the sw_data
> + * field as a 32bit value. Will not work on 64bit machines
> + */
> + buf_ptr = (void *)GET_SW_DATA0(ndesc);
> + buf_len = (int)GET_SW_DATA1(desc);
I would have abstracted the retrieval of a pointer again,
and added the comment in the helper function once, it doesn't
really need to be duplicated everywhere.
Arnd
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/3] soc: ti: knav_dma: rename pad in struct knav_dma_desc to sw_data
2016-02-19 17:58 ` [PATCH v2 2/3] soc: ti: knav_dma: rename pad in struct knav_dma_desc to sw_data Murali Karicheri
@ 2016-02-19 20:55 ` Arnd Bergmann
0 siblings, 0 replies; 11+ messages in thread
From: Arnd Bergmann @ 2016-02-19 20:55 UTC (permalink / raw)
To: Murali Karicheri; +Cc: linux-kernel, netdev, davem
On Friday 19 February 2016 12:58:43 Murali Karicheri wrote:
> Rename the pad to sw_data as per description of this field in the hardware
> spec(refer sprugr9 from www.ti.com). Latest version of the document is
> at http://www.ti.com/lit/ug/sprugr9h/sprugr9h.pdf and section 3.1
> Host Packet Descriptor describes this field.
>
> Define and use a constant for the size of sw_data field similar to
> other fields in the struct for desc and document the sw_data field
> in the header. As the sw_data is not touched by hw, it's type can be
> changed to u32.
>
> Rename the helpers to match with the updated dma desc field sw_data.
>
> Cc: Wingman Kwok <w-kwok2@ti.com>
> Cc: Mugunthan V N <mugunthanvnm@ti.com>
> CC: Arnd Bergmann <arnd@arndb.de>
> CC: Grygorii Strashko <grygorii.strashko@ti.com>
> CC: David Laight <David.Laight@ACULAB.COM>
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
>
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 1/3] net: ti: netcp: restore get/set_pad_info() functionality
2016-02-19 17:58 ` [PATCH v2 1/3] " Murali Karicheri
@ 2016-02-19 20:56 ` Arnd Bergmann
0 siblings, 0 replies; 11+ messages in thread
From: Arnd Bergmann @ 2016-02-19 20:56 UTC (permalink / raw)
To: Murali Karicheri; +Cc: linux-kernel, netdev, davem
On Friday 19 February 2016 12:58:42 Murali Karicheri wrote:
> The commit 899077791403 ("netcp: try to reduce type confusion in
> descriptors") introduces a regression in Kernel 4.5-rc1 and it breaks
> get/set_pad_info() functionality.
>
> The TI NETCP driver uses pad0 and pad1 fields of knav_dma_desc to
> store DMA/MEM buffer pointer and buffer size respectively. And in both
> cases for Keystone 2 the pointer type size is 32 bit regardless of
> LAPE enabled or not, because CONFIG_ARCH_DMA_ADDR_T_64BIT originally
> is not expected to be defined.
>
> Unfortunately, above commit changed buffer's pointers save/restore
> code (get/set_pad_info()) and added intermediate conversation to u64
> which works incorrectly on 32bit Keystone 2 and causes TI NETCP driver
> crash in RX/TX path due to "Unable to handle kernel NULL pointer"
> exception. This issue was reported and discussed in [1].
>
> Hence, fix it by partially reverting above commit and restoring
> get/set_pad_info() functionality as it was before.
>
> [1] https://www.mail-archive.com/netdev@vger.kernel.org/msg95361.html
> Cc: Wingman Kwok <w-kwok2@ti.com>
> Cc: Mugunthan V N <mugunthanvnm@ti.com>
> CC: David Laight <David.Laight@ACULAB.COM>
> CC: Arnd Bergmann <arnd@arndb.de>
> Reported-by: Franklin S Cooper Jr <fcooper@ti.com>
> Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
>
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 3/3] net: netcp: rework the code for get/set sw_data in dma desc
2016-02-19 20:55 ` Arnd Bergmann
@ 2016-02-19 22:21 ` Murali Karicheri
2016-02-19 22:25 ` Arnd Bergmann
0 siblings, 1 reply; 11+ messages in thread
From: Murali Karicheri @ 2016-02-19 22:21 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linux-kernel, netdev, davem
On 02/19/2016 03:55 PM, Arnd Bergmann wrote:
> On Friday 19 February 2016 12:58:44 Murali Karicheri wrote:
>> SW data field in descriptor can be used by software to hold private
>> data for the driver. As there are 4 words available for this purpose,
>> use separate macros to place it or retrieve the same to/from
>> descriptors. Also do type cast of data types accordingly.
>>
>> Cc: Wingman Kwok <w-kwok2@ti.com>
>> Cc: Mugunthan V N <mugunthanvnm@ti.com>
>> CC: Arnd Bergmann <arnd@arndb.de>
>> CC: Grygorii Strashko <grygorii.strashko@ti.com>
>> CC: David Laight <David.Laight@ACULAB.COM>
>> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com>
>
> Looks ok in principle.
>
> Acked-by: Arnd Bergmann <arnd@arndb.de>
>
>> get_pkt_info(&dma_buf, &tmp, &dma_desc, ndesc);
>> - get_sw_data((u32 *)&buf_ptr, &buf_len, ndesc);
>> + /* warning!!!! We are retrieving the virtual ptr in the sw_data
>> + * field as a 32bit value. Will not work on 64bit machines
>> + */
>> + buf_ptr = (void *)GET_SW_DATA0(ndesc);
>> + buf_len = (int)GET_SW_DATA1(desc);
>
> I would have abstracted the retrieval of a pointer again,
> and added the comment in the helper function once, it doesn't
> really need to be duplicated everywhere.
>
Arnd,
I thought about it to add it to the API. API currently set buffer
and ptr. It would be an issue only if store/retrieve ptr in/from the sw_data.
So for the comment to be really useful to someone who is changing the code,
doesn't it make sense to add it at the point of invocation as done in this
patch? No?
Murali
> Arnd
>
--
Murali Karicheri
Linux Kernel, Keystone
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 3/3] net: netcp: rework the code for get/set sw_data in dma desc
2016-02-19 22:21 ` Murali Karicheri
@ 2016-02-19 22:25 ` Arnd Bergmann
2016-02-22 17:04 ` Murali Karicheri
0 siblings, 1 reply; 11+ messages in thread
From: Arnd Bergmann @ 2016-02-19 22:25 UTC (permalink / raw)
To: Murali Karicheri; +Cc: linux-kernel, netdev, davem
On Friday 19 February 2016 17:21:57 Murali Karicheri wrote:
> >> get_pkt_info(&dma_buf, &tmp, &dma_desc, ndesc);
> >> - get_sw_data((u32 *)&buf_ptr, &buf_len, ndesc);
> >> + /* warning!!!! We are retrieving the virtual ptr in the sw_data
> >> + * field as a 32bit value. Will not work on 64bit machines
> >> + */
> >> + buf_ptr = (void *)GET_SW_DATA0(ndesc);
> >> + buf_len = (int)GET_SW_DATA1(desc);
> >
> > I would have abstracted the retrieval of a pointer again,
> > and added the comment in the helper function once, it doesn't
> > really need to be duplicated everywhere.
> >
> Arnd,
>
> I thought about it to add it to the API. API currently set buffer
> and ptr. It would be an issue only if store/retrieve ptr in/from the sw_data.
> So for the comment to be really useful to someone who is changing the code,
> doesn't it make sense to add it at the point of invocation as done in this
> patch? No?
>
Up to you, it was just an idea and you have my Ack either way.
Arnd
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 0/3] net: ti: netcp: restore get/set_pad_info() functionality
2016-02-19 17:58 [PATCH v2 0/3] net: ti: netcp: restore get/set_pad_info() functionality Murali Karicheri
` (2 preceding siblings ...)
2016-02-19 17:58 ` [PATCH v2 3/3] net: netcp: rework the code for get/set sw_data in dma desc Murali Karicheri
@ 2016-02-22 3:02 ` David Miller
3 siblings, 0 replies; 11+ messages in thread
From: David Miller @ 2016-02-22 3:02 UTC (permalink / raw)
To: m-karicheri2; +Cc: linux-kernel, netdev, arnd
From: Murali Karicheri <m-karicheri2@ti.com>
Date: Fri, 19 Feb 2016 12:58:41 -0500
> This series fixes a regression and add some improvements for the ease
> of maintainance. Incorporated comments against v1.
>
> Changelogs:
>
> v2 : combined 2-3 into one patch as this involves a header change
> fixed a parse warning in 3/4 per comment from Arnd.
> Removed Sign-off from Arnd against 1/4
> added comments in 3/3 to alert on the usage of sw data per review
> comments
> v1 : added 2-4 to accomodate feedback received from review
> v0 : initial version to fix the regression (From Grygorii)
Series applied, thanks.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 3/3] net: netcp: rework the code for get/set sw_data in dma desc
2016-02-19 22:25 ` Arnd Bergmann
@ 2016-02-22 17:04 ` Murali Karicheri
0 siblings, 0 replies; 11+ messages in thread
From: Murali Karicheri @ 2016-02-22 17:04 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linux-kernel, netdev, davem
On 02/19/2016 05:25 PM, Arnd Bergmann wrote:
> On Friday 19 February 2016 17:21:57 Murali Karicheri wrote:
>>>> get_pkt_info(&dma_buf, &tmp, &dma_desc, ndesc);
>>>> - get_sw_data((u32 *)&buf_ptr, &buf_len, ndesc);
>>>> + /* warning!!!! We are retrieving the virtual ptr in the sw_data
>>>> + * field as a 32bit value. Will not work on 64bit machines
>>>> + */
>>>> + buf_ptr = (void *)GET_SW_DATA0(ndesc);
>>>> + buf_len = (int)GET_SW_DATA1(desc);
>>>
>>> I would have abstracted the retrieval of a pointer again,
>>> and added the comment in the helper function once, it doesn't
>>> really need to be duplicated everywhere.
>>>
>> Arnd,
>>
>> I thought about it to add it to the API. API currently set buffer
>> and ptr. It would be an issue only if store/retrieve ptr in/from the sw_data.
>> So for the comment to be really useful to someone who is changing the code,
>> doesn't it make sense to add it at the point of invocation as done in this
>> patch? No?
>>
>
> Up to you, it was just an idea and you have my Ack either way.
>
> Arnd
>
Ok. Thanks
--
Murali Karicheri
Linux Kernel, Keystone
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2016-02-22 17:04 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-19 17:58 [PATCH v2 0/3] net: ti: netcp: restore get/set_pad_info() functionality Murali Karicheri
2016-02-19 17:58 ` [PATCH v2 1/3] " Murali Karicheri
2016-02-19 20:56 ` Arnd Bergmann
2016-02-19 17:58 ` [PATCH v2 2/3] soc: ti: knav_dma: rename pad in struct knav_dma_desc to sw_data Murali Karicheri
2016-02-19 20:55 ` Arnd Bergmann
2016-02-19 17:58 ` [PATCH v2 3/3] net: netcp: rework the code for get/set sw_data in dma desc Murali Karicheri
2016-02-19 20:55 ` Arnd Bergmann
2016-02-19 22:21 ` Murali Karicheri
2016-02-19 22:25 ` Arnd Bergmann
2016-02-22 17:04 ` Murali Karicheri
2016-02-22 3:02 ` [PATCH v2 0/3] net: ti: netcp: restore get/set_pad_info() functionality David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).