netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] atm: Replace in_interrupt usage
@ 2020-11-16 16:21 Sebastian Andrzej Siewior
  2020-11-16 16:21 ` [PATCH 1/3] atm: nicstar: Unmap DMA on send error Sebastian Andrzej Siewior
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Sebastian Andrzej Siewior @ 2020-11-16 16:21 UTC (permalink / raw)
  To: linux-atm-general; +Cc: Chas Williams, netdev, Thomas Gleixner

Folks,

this mini series contains the removal of in_interrupt() in drivers/atm
and a tiny bugfix while staring into code.

Sebastian



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/3] atm: nicstar: Unmap DMA on send error
  2020-11-16 16:21 [PATCH 0/3] atm: Replace in_interrupt usage Sebastian Andrzej Siewior
@ 2020-11-16 16:21 ` Sebastian Andrzej Siewior
  2020-11-16 16:21 ` [PATCH 2/3] atm: nicstar: Replace in_interrupt() usage Sebastian Andrzej Siewior
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Sebastian Andrzej Siewior @ 2020-11-16 16:21 UTC (permalink / raw)
  To: linux-atm-general
  Cc: Chas Williams, netdev, Thomas Gleixner, Sebastian Andrzej Siewior

The `skb' is mapped for DMA in ns_send() but does not unmap DMA in case
push_scqe() fails to submit the `skb'. The memory of the `skb' is
released so only the DMA mapping is leaking.

Unmap the DMA mapping in case push_scqe() failed.

Fixes: 864a3ff635fa7 ("atm: [nicstar] remove virt_to_bus() and support 64-bit platforms")
Cc: Chas Williams <3chas3@gmail.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/atm/nicstar.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index 7af74fb450a0d..09ad73361879e 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -1706,6 +1706,8 @@ static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb)
 
 	if (push_scqe(card, vc, scq, &scqe, skb) != 0) {
 		atomic_inc(&vcc->stats->tx_err);
+		dma_unmap_single(&card->pcidev->dev, NS_PRV_DMA(skb), skb->len,
+				 DMA_TO_DEVICE);
 		dev_kfree_skb_any(skb);
 		return -EIO;
 	}
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/3] atm: nicstar: Replace in_interrupt() usage
  2020-11-16 16:21 [PATCH 0/3] atm: Replace in_interrupt usage Sebastian Andrzej Siewior
  2020-11-16 16:21 ` [PATCH 1/3] atm: nicstar: Unmap DMA on send error Sebastian Andrzej Siewior
@ 2020-11-16 16:21 ` Sebastian Andrzej Siewior
  2020-11-16 16:21 ` [PATCH 3/3] atm: lanai: Remove " Sebastian Andrzej Siewior
  2020-11-19  0:45 ` [PATCH 0/3] atm: Replace in_interrupt usage Jakub Kicinski
  3 siblings, 0 replies; 5+ messages in thread
From: Sebastian Andrzej Siewior @ 2020-11-16 16:21 UTC (permalink / raw)
  To: linux-atm-general
  Cc: Chas Williams, netdev, Thomas Gleixner,
	Sebastian Andrzej Siewior, Jakub Kicinski

push_scqe() uses in_interrupt() to figure out if it is allowed to sleep.

The usage of in_interrupt() in drivers is phased out and Linus clearly
requested that code which changes behaviour depending on context should
either be separated or the context be conveyed in an argument passed by the
caller, which usually knows the context.

Aside of that in_interrupt() is not correct as it does not catch preempt
disabled regions which neither can sleep.

ns_send() (the only caller of push_scqe()) has the following callers:

- vcc_sendmsg() used as proto_ops::sendmsg is expected to be invoked in
  preemtible context.
  -> vcc->dev->ops->send() (ns_send())

- atm_vcc::send via atmdev_ops::send either directly (pointer copied by
  atm_init_aal34() or atm_init_aal5()) or via atm_send_aal0().
  This is invoked by drivers (like br2684, clip, pppoatm, ...) which are
  called from net_device_ops::ndo_start_xmit with BH disabled.

Add atmdev_ops::send_bh which is used by callers from BH context
(atm_send_aal*()) and if this callback missing then ::send is used
instead.
Implement this callback in nicstar and use it to replace in_interrupt().

Cc: netdev@vger.kernel.org
Cc: Chas Williams <3chas3@gmail.com>
CC: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/atm/nicstar.c  | 24 ++++++++++++++++++------
 include/linux/atmdev.h |  1 +
 net/atm/raw.c          | 12 ++++++++++--
 3 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index 09ad73361879e..5c7e4df159b91 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -130,8 +130,9 @@ static int ns_open(struct atm_vcc *vcc);
 static void ns_close(struct atm_vcc *vcc);
 static void fill_tst(ns_dev * card, int n, vc_map * vc);
 static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb);
+static int ns_send_bh(struct atm_vcc *vcc, struct sk_buff *skb);
 static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd,
-		     struct sk_buff *skb);
+		     struct sk_buff *skb, bool may_sleep);
 static void process_tsq(ns_dev * card);
 static void drain_scq(ns_dev * card, scq_info * scq, int pos);
 static void process_rsq(ns_dev * card);
@@ -160,6 +161,7 @@ static const struct atmdev_ops atm_ops = {
 	.close = ns_close,
 	.ioctl = ns_ioctl,
 	.send = ns_send,
+	.send_bh = ns_send_bh,
 	.phy_put = ns_phy_put,
 	.phy_get = ns_phy_get,
 	.proc_read = ns_proc_read,
@@ -1620,7 +1622,7 @@ static void fill_tst(ns_dev * card, int n, vc_map * vc)
 	card->tst_addr = new_tst;
 }
 
-static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb)
+static int _ns_send(struct atm_vcc *vcc, struct sk_buff *skb, bool may_sleep)
 {
 	ns_dev *card;
 	vc_map *vc;
@@ -1704,7 +1706,7 @@ static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb)
 		scq = card->scq0;
 	}
 
-	if (push_scqe(card, vc, scq, &scqe, skb) != 0) {
+	if (push_scqe(card, vc, scq, &scqe, skb, may_sleep) != 0) {
 		atomic_inc(&vcc->stats->tx_err);
 		dma_unmap_single(&card->pcidev->dev, NS_PRV_DMA(skb), skb->len,
 				 DMA_TO_DEVICE);
@@ -1716,8 +1718,18 @@ static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb)
 	return 0;
 }
 
+static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb)
+{
+	return _ns_send(vcc, skb, true);
+}
+
+static int ns_send_bh(struct atm_vcc *vcc, struct sk_buff *skb)
+{
+	return _ns_send(vcc, skb, false);
+}
+
 static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd,
-		     struct sk_buff *skb)
+		     struct sk_buff *skb, bool may_sleep)
 {
 	unsigned long flags;
 	ns_scqe tsr;
@@ -1728,7 +1740,7 @@ static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd,
 
 	spin_lock_irqsave(&scq->lock, flags);
 	while (scq->tail == scq->next) {
-		if (in_interrupt()) {
+		if (!may_sleep) {
 			spin_unlock_irqrestore(&scq->lock, flags);
 			printk("nicstar%d: Error pushing TBD.\n", card->index);
 			return 1;
@@ -1773,7 +1785,7 @@ static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd,
 		int has_run = 0;
 
 		while (scq->tail == scq->next) {
-			if (in_interrupt()) {
+			if (!may_sleep) {
 				data = scq_virt_to_bus(scq, scq->next);
 				ns_write_sram(card, scq->scd, &data, 1);
 				spin_unlock_irqrestore(&scq->lock, flags);
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index 5d5ff2203fa22..d7493016cd466 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -186,6 +186,7 @@ struct atmdev_ops { /* only send is required */
 			    void __user *arg);
 #endif
 	int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
+	int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb);
 	int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
 	void (*phy_put)(struct atm_dev *dev,unsigned char value,
 	    unsigned long addr);
diff --git a/net/atm/raw.c b/net/atm/raw.c
index b3ba44aab0ee6..2b5f78a7ec3e4 100644
--- a/net/atm/raw.c
+++ b/net/atm/raw.c
@@ -54,6 +54,8 @@ static int atm_send_aal0(struct atm_vcc *vcc, struct sk_buff *skb)
 		kfree_skb(skb);
 		return -EADDRNOTAVAIL;
 	}
+	if (vcc->dev->ops->send_bh)
+		return vcc->dev->ops->send_bh(vcc, skb);
 	return vcc->dev->ops->send(vcc, skb);
 }
 
@@ -71,7 +73,10 @@ int atm_init_aal34(struct atm_vcc *vcc)
 	vcc->push = atm_push_raw;
 	vcc->pop = atm_pop_raw;
 	vcc->push_oam = NULL;
-	vcc->send = vcc->dev->ops->send;
+	if (vcc->dev->ops->send_bh)
+		vcc->send = vcc->dev->ops->send_bh;
+	else
+		vcc->send = vcc->dev->ops->send;
 	return 0;
 }
 
@@ -80,7 +85,10 @@ int atm_init_aal5(struct atm_vcc *vcc)
 	vcc->push = atm_push_raw;
 	vcc->pop = atm_pop_raw;
 	vcc->push_oam = NULL;
-	vcc->send = vcc->dev->ops->send;
+	if (vcc->dev->ops->send_bh)
+		vcc->send = vcc->dev->ops->send_bh;
+	else
+		vcc->send = vcc->dev->ops->send;
 	return 0;
 }
 EXPORT_SYMBOL(atm_init_aal5);
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 3/3] atm: lanai: Remove in_interrupt() usage
  2020-11-16 16:21 [PATCH 0/3] atm: Replace in_interrupt usage Sebastian Andrzej Siewior
  2020-11-16 16:21 ` [PATCH 1/3] atm: nicstar: Unmap DMA on send error Sebastian Andrzej Siewior
  2020-11-16 16:21 ` [PATCH 2/3] atm: nicstar: Replace in_interrupt() usage Sebastian Andrzej Siewior
@ 2020-11-16 16:21 ` Sebastian Andrzej Siewior
  2020-11-19  0:45 ` [PATCH 0/3] atm: Replace in_interrupt usage Jakub Kicinski
  3 siblings, 0 replies; 5+ messages in thread
From: Sebastian Andrzej Siewior @ 2020-11-16 16:21 UTC (permalink / raw)
  To: linux-atm-general
  Cc: Chas Williams, netdev, Thomas Gleixner, Sebastian Andrzej Siewior

lanai_shutdown_tx_vci() uses in_interrupt() to issue a warning message
if the function was used in context in which it is not safe to sleep.

The usage of in_interrupt() in driver code is deprecated as it can not always
detect all states where it is not allowed to sleep.

msleep() has debug code which will trigger a warning if used in bad
context.

Remove in_interrupt().

Cc: Chas Williams <3chas3@gmail.com>
Cc: netdev@vger.kernel.org
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 drivers/atm/lanai.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index ac811cfa68431..d7277c26e4232 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -765,8 +765,7 @@ static void lanai_shutdown_tx_vci(struct lanai_dev *lanai,
 	struct sk_buff *skb;
 	unsigned long flags, timeout;
 	int read, write, lastread = -1;
-	APRINTK(!in_interrupt(),
-	    "lanai_shutdown_tx_vci called w/o process context!\n");
+
 	if (lvcc->vbase == NULL)	/* We were never bound to a VCI */
 		return;
 	/* 15.2.1 - wait for queue to drain */
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/3] atm: Replace in_interrupt usage
  2020-11-16 16:21 [PATCH 0/3] atm: Replace in_interrupt usage Sebastian Andrzej Siewior
                   ` (2 preceding siblings ...)
  2020-11-16 16:21 ` [PATCH 3/3] atm: lanai: Remove " Sebastian Andrzej Siewior
@ 2020-11-19  0:45 ` Jakub Kicinski
  3 siblings, 0 replies; 5+ messages in thread
From: Jakub Kicinski @ 2020-11-19  0:45 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: linux-atm-general, Chas Williams, netdev, Thomas Gleixner

On Mon, 16 Nov 2020 17:21:13 +0100 Sebastian Andrzej Siewior wrote:
> Folks,
> 
> this mini series contains the removal of in_interrupt() in drivers/atm
> and a tiny bugfix while staring into code.

Applied, thanks.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-11-19  0:45 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-16 16:21 [PATCH 0/3] atm: Replace in_interrupt usage Sebastian Andrzej Siewior
2020-11-16 16:21 ` [PATCH 1/3] atm: nicstar: Unmap DMA on send error Sebastian Andrzej Siewior
2020-11-16 16:21 ` [PATCH 2/3] atm: nicstar: Replace in_interrupt() usage Sebastian Andrzej Siewior
2020-11-16 16:21 ` [PATCH 3/3] atm: lanai: Remove " Sebastian Andrzej Siewior
2020-11-19  0:45 ` [PATCH 0/3] atm: Replace in_interrupt usage Jakub Kicinski

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).