All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vitalii Demianets <vitas@nppfactor.kiev.ua>
To: linux-kernel@vger.kernel.org
Cc: "Hans J. Koch" <hjk@hansjkoch.de>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	Cong Ding <dinggnu@gmail.com>
Subject: [PATCH 2/2] Fix concurrency issue
Date: Mon, 10 Dec 2012 11:46:07 +0200	[thread overview]
Message-ID: <201212101146.07235.vitas@nppfactor.kiev.ua> (raw)
In-Reply-To: <201212101118.08463.vitas@nppfactor.kiev.ua>

In a SMP case there was a race condition issue between
uio_pdrv_genirq_irqcontrol() running on one CPU and irq handler on another
CPU. Fix it by spin_locking shared resources access inside irq handler.
Also:
 - Change disable_irq to disable_irq_nosync to avoid deadlock, because
disable_irq waits for the completion of the irq handler
 - Change atomic bit-manipulation routines to their non-atomic counterparts as
we already are guarding the code by spinlock.

Signed-off-by: Vitalii Demianets <vitas@nppfactor.kiev.ua>
---
 drivers/uio/uio_pdrv_genirq.c |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
index cc5233b..8075367 100644
--- a/drivers/uio/uio_pdrv_genirq.c
+++ b/drivers/uio/uio_pdrv_genirq.c
@@ -68,8 +68,10 @@ static irqreturn_t uio_pdrv_genirq_handler(int irq, struct uio_info *dev_info)
 	 * remember the state so we can allow user space to enable it later.
 	 */
 
-	if (!test_and_set_bit(UIO_IRQ_DISABLED, &priv->flags))
+	spin_lock(&priv->lock);
+	if (!__test_and_set_bit(UIO_IRQ_DISABLED, &priv->flags))
 		disable_irq_nosync(irq);
+	spin_unlock(&priv->lock);
 
 	return IRQ_HANDLED;
 }
@@ -83,16 +85,17 @@ static int uio_pdrv_genirq_irqcontrol(struct uio_info *dev_info, s32 irq_on)
 	 * in the interrupt controller, but keep track of the
 	 * state to prevent per-irq depth damage.
 	 *
-	 * Serialize this operation to support multiple tasks.
+	 * Serialize this operation to support multiple tasks and concurrency
+	 * with irq handler on SMP systems.
 	 */
 
 	spin_lock_irqsave(&priv->lock, flags);
 	if (irq_on) {
-		if (test_and_clear_bit(UIO_IRQ_DISABLED, &priv->flags))
+		if (__test_and_clear_bit(UIO_IRQ_DISABLED, &priv->flags))
 			enable_irq(dev_info->irq);
 	} else {
-		if (!test_and_set_bit(UIO_IRQ_DISABLED, &priv->flags))
-			disable_irq(dev_info->irq);
+		if (!__test_and_set_bit(UIO_IRQ_DISABLED, &priv->flags))
+			disable_irq_nosync(dev_info->irq);
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-- 
1.7.8.6

      parent reply	other threads:[~2012-12-10  9:46 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-10  9:18 [PATCH 0/2] drivers/uio/uio_pdrv_genirq.c: FIx memory & concurrency issues Vitalii Demianets
2012-12-10  9:44 ` [PATCH 1/2 v3] Fix memory freeing issues Vitalii Demianets
2012-12-13 18:13   ` Hans J. Koch
2012-12-14  9:33     ` Vitalii Demianets
2012-12-15 17:25       ` Hans J. Koch
2012-12-17  8:58         ` Vitalii Demianets
2012-12-10  9:46 ` Vitalii Demianets [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201212101146.07235.vitas@nppfactor.kiev.ua \
    --to=vitas@nppfactor.kiev.ua \
    --cc=dinggnu@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hjk@hansjkoch.de \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.