[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20191207120238.GB2798@khorivan>
Date: Sat, 7 Dec 2019 14:02:39 +0200
From: Ivan Khoronzhuk <ivan.khoronzhuk@...aro.org>
To: Grygorii Strashko <grygorii.strashko@...com>,
David Miller <davem@...emloft.net>, netdev@...r.kernel.org,
nsekhar@...com, linux-kernel@...r.kernel.org
Subject: Re: [PATCH v2] net: ethernet: ti: davinci_cpdma: fix warning "device
driver frees DMA memory with different size"
On Sat, Dec 07, 2019 at 01:44:20PM +0200, Ivan Khoronzhuk wrote:
>On Thu, Dec 05, 2019 at 12:48:46PM +0200, Grygorii Strashko wrote:
>>
>>
>>On 04/12/2019 22:37, David Miller wrote:
>>>From: Grygorii Strashko <grygorii.strashko@...com>
>>>Date: Wed, 4 Dec 2019 18:50:29 +0200
>>>
>>>>@@ -1018,7 +1018,7 @@ static int cpdma_chan_submit_si(struct submit_info *si)
>>>> struct cpdma_chan *chan = si->chan;
>>>> struct cpdma_ctlr *ctlr = chan->ctlr;
>>>> int len = si->len;
>>>>- int swlen = len;
>>>>+ int swlen;
>>>> struct cpdma_desc __iomem *desc;
>>>> dma_addr_t buffer;
>>>> u32 mode;
>>>>@@ -1040,6 +1040,7 @@ static int cpdma_chan_submit_si(struct submit_info *si)
>>>> chan->stats.runt_transmit_buff++;
>>>> }
>>>>+ swlen = len;
>>>> mode = CPDMA_DESC_OWNER | CPDMA_DESC_SOP | CPDMA_DESC_EOP;
>>>> cpdma_desc_to_port(chan, mode, si->directed);
>>>>--
>>>>2.17.1
>>>>
>>>
>>>Now there is no reason to keep a separate swlen variable.
>>>
>>>The integral value is always consumed as the length before the descriptor bits
>>>are added to it.
>>>
>>>Therefore you can just use 'len' everywhere in this function now.
>>>
>>
>>Sry, but seems i can't, at least i can't just drop swlen.
>>
>>Below in this function:
>> writel_relaxed(0, &desc->hw_next);
>> writel_relaxed(buffer, &desc->hw_buffer);
>> writel_relaxed(len, &desc->hw_len);
>> writel_relaxed(mode | len, &desc->hw_mode);
>>^^ here the "len" should be use
>>
>> writel_relaxed((uintptr_t)si->token, &desc->sw_token);
>> writel_relaxed(buffer, &desc->sw_buffer);
>> writel_relaxed(swlen, &desc->sw_len);
>>^^ and here "len"|CPDMA_DMA_EXT_MAP if (si->data_dma) [1]
>>
>> desc_read(desc, sw_len);
>>
>>so additional if statement has to be added at [1] if "swlen" is dropped
>>
>>--
>>Best regards,
>>grygorii
>
>Seems like yes,
>
>And the "swlen" can be avoided like this:
>
>--- a/drivers/net/ethernet/ti/davinci_cpdma.c
>+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
>@@ -1018,7 +1018,6 @@ static int cpdma_chan_submit_si(struct submit_info *si)
> struct cpdma_chan *chan = si->chan;
> struct cpdma_ctlr *ctlr = chan->ctlr;
> int len = si->len;
>- int swlen = len;
> struct cpdma_desc __iomem *desc;
> dma_addr_t buffer;
> u32 mode;
>@@ -1046,7 +1045,7 @@ static int cpdma_chan_submit_si(struct submit_info *si)
> if (si->data_dma) {
> buffer = si->data_dma;
> dma_sync_single_for_device(ctlr->dev, buffer, len, chan->dir);
>- swlen |= CPDMA_DMA_EXT_MAP;
>+ writel_relaxed(len | CPDMA_DMA_EXT_MAP, &desc->sw_len);
> } else {
> buffer = dma_map_single(ctlr->dev, si->data_virt, len, chan->dir);
> ret = dma_mapping_error(ctlr->dev, buffer);
>@@ -1054,6 +1053,7 @@ static int cpdma_chan_submit_si(struct submit_info *si)
> cpdma_desc_free(ctlr->pool, desc, 1);
> return -EINVAL;
> }
>+ writel_relaxed(len, &desc->sw_len);
> }
>
> /* Relaxed IO accessors can be used here as there is read barrier
>@@ -1065,7 +1065,6 @@ static int cpdma_chan_submit_si(struct submit_info *si)
> writel_relaxed(mode | len, &desc->hw_mode);
> writel_relaxed((uintptr_t)si->token, &desc->sw_token);
> writel_relaxed(buffer, &desc->sw_buffer);
>- writel_relaxed(swlen, &desc->sw_len);
> desc_read(desc, sw_len);
>
> __cpdma_chan_submit(chan, desc);
>
>But not sure what is better.
>
Or like this:
--- a/drivers/net/ethernet/ti/davinci_cpdma.c
+++ b/drivers/net/ethernet/ti/davinci_cpdma.c
@@ -1018,7 +1018,6 @@ static int cpdma_chan_submit_si(struct submit_info *si)
struct cpdma_chan *chan = si->chan;
struct cpdma_ctlr *ctlr = chan->ctlr;
int len = si->len;
- int swlen = len;
struct cpdma_desc __iomem *desc;
dma_addr_t buffer;
u32 mode;
@@ -1046,7 +1045,6 @@ static int cpdma_chan_submit_si(struct submit_info *si)
if (si->data_dma) {
buffer = si->data_dma;
dma_sync_single_for_device(ctlr->dev, buffer, len, chan->dir);
- swlen |= CPDMA_DMA_EXT_MAP;
} else {
buffer = dma_map_single(ctlr->dev, si->data_virt, len, chan->dir);
ret = dma_mapping_error(ctlr->dev, buffer);
@@ -1065,7 +1063,7 @@ static int cpdma_chan_submit_si(struct submit_info *si)
writel_relaxed(mode | len, &desc->hw_mode);
writel_relaxed((uintptr_t)si->token, &desc->sw_token);
writel_relaxed(buffer, &desc->sw_buffer);
- writel_relaxed(swlen, &desc->sw_len);
+ writel_relaxed(si->data_dma ? len | CPDMA_DMA_EXT_MAP : len, &desc->sw_len);
desc_read(desc, sw_len);
__cpdma_chan_submit(chan, desc);
But it's branched twice then.
--
Regards,
Ivan Khoronzhuk
Powered by blists - more mailing lists