[PATCH 2/3] omap mailbox: prevent multiple concurrent receivers race

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: ext Ohad Ben-Cohen <ohad@xxxxxxxxxx>

We currently maintain only a single mailbox receiver callback.
To prevent multiple receivers race scenarios (in which receivers
will end up overwriting each other's callback pointers), we make
sure that mailbox instances cannot be taken by more than
one receiver at the same time.

Signed-off-by: Ohad Ben-Cohen <ohad@xxxxxxxxxx>
Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@xxxxxxxxx>
---
 arch/arm/plat-omap/include/plat/mailbox.h |    1 +
 arch/arm/plat-omap/mailbox.c              |   12 +++++++++++-
 2 files changed, 12 insertions(+), 1 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/mailbox.h b/arch/arm/plat-omap/include/plat/mailbox.h
index 0b45664..5df35b4 100644
--- a/arch/arm/plat-omap/include/plat/mailbox.h
+++ b/arch/arm/plat-omap/include/plat/mailbox.h
@@ -57,6 +57,7 @@ struct omap_mbox {
 	struct omap_mbox_ops	*ops;
 	struct device		*dev;
 	void			*priv;
+	atomic_t		count;
 };
 
 int omap_mbox_msg_send(struct omap_mbox *, mbox_msg_t msg);
diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
index 14b716d..aafa63f 100644
--- a/arch/arm/plat-omap/mailbox.c
+++ b/arch/arm/plat-omap/mailbox.c
@@ -320,9 +320,17 @@ struct omap_mbox *omap_mbox_get(const char *name, int (*callback)(void *))
 	if (!mbox)
 		return ERR_PTR(-ENOENT);
 
+	if (atomic_inc_return(&mbox->count) > 1) {
+		pr_err("%s: mbox %s already in use\n", __func__, name);
+		atomic_dec(&mbox->count);
+		return ERR_PTR(-EBUSY);
+	}
+
 	ret = omap_mbox_startup(mbox);
-	if (ret)
+	if (ret) {
+		atomic_dec(&mbox->count);
 		return ERR_PTR(-ENODEV);
+	}
 
 	mbox->rxq->callback = callback;
 
@@ -333,6 +341,7 @@ EXPORT_SYMBOL(omap_mbox_get);
 void omap_mbox_put(struct omap_mbox *mbox)
 {
 	omap_mbox_fini(mbox);
+	atomic_dec(&mbox->count);
 }
 EXPORT_SYMBOL(omap_mbox_put);
 
@@ -349,6 +358,7 @@ int omap_mbox_register(struct device *parent, struct omap_mbox **list)
 
 	for (i = 0; mboxes[i]; i++) {
 		struct omap_mbox *mbox = mboxes[i];
+		atomic_set(&mbox->count, 0);
 		mbox->dev = device_create(&omap_mbox_class,
 				parent, 0, mbox, "%s", mbox->name);
 		if (IS_ERR(mbox->dev)) {
-- 
1.7.1.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux