Messages in this thread Patch in this message | | | Date | Thu, 29 Nov 2012 13:43:44 +0100 | From | Krzysztof Mazur <> | Subject | [PATCH] solos-pci: don't call vcc->pop() after pclose() |
| |
On Thu, Nov 29, 2012 at 11:55:43AM +0000, David Woodhouse wrote: > On Thu, 2012-11-29 at 11:57 +0100, Krzysztof Mazur wrote: > > do we really need to wait here? > > Why don't just do something like that: > > > > tasklet_disable(&card->tlet); > > spin_lock(&card->tx_queue_lock); > > for each skb in queue > > SKB_CB(skb)->vcc = NULL; > > spin_unlock(&card->tx_queue_lock); > > tasklet_enable(&card->tlet); > > > > or if we really want to call vcc->pop() for such skbs: > > > > tasklet_disable(&card->tlet); > > spin_lock(&card->tx_queue_lock); > > for each skb in queue { > > skb_get(skb); > > solos_pop(SKB_CB(skb)->vcc, skb); > > SKB_CB(skb)->vcc = NULL; > > } > > spin_unlock(&card->tx_queue_lock); > > tasklet_enable(&card->tlet); > > Yes, we could certainly remove the packets from the tx_queue first. > > However, in the card->using_dma case there might be a skb for this vcc > *currently* being DMA'd, and we'd still need to wait for that one.
Removing packets from tx_queue is not needed. We can transmit packets also after close. We just can't call vcc->pop() after close, so we can just set SKB_CB(skb)->vcc of such packets to NULL so fpga_tx() won't call vcc->pop().
Maybe I was not precise enough, I'm think that all we need is something like that:
-- >8 -- Subject: [PATCH] solos-pci: don't call vcc->pop() after pclose()
After atmdev_ops->close() we cannot use vcc->pop() because the vcc may, and probably will be destroyed.
We can just set vcc for such frames to NULL because fpga_tx() after completion will call dev_kfree_skb() in that case.
Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net> --- drivers/atm/solos-pci.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 9851093..aabe021 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -868,6 +868,19 @@ static void pclose(struct atm_vcc *vcc) struct solos_card *card = vcc->dev->dev_data; struct sk_buff *skb; struct pkt_hdr *header; + unsigned int port; + + tasklet_disable(&card->tlet); + spin_lock(&card->tx_queue_lock); + for (port = 0; port < card->nr_ports; port++) + skb_queue_walk(&card->tx_queue[port], skb) + if (SKB_CB(skb)->vcc == vcc) { + skb_get(skb); + solos_pop(SKB_CB(skb)->vcc, skb); + SKB_CB(skb)->vcc = NULL; + } + spin_unlock(&card->tx_queue_lock); + tasklet_enable(&card->tlet); skb = alloc_skb(sizeof(*header), GFP_ATOMIC); if (!skb) { -- 1.8.0.411.g71a7da8
| |