xpp: Serialize dahdi registration

xpp: Serialize dahdi registration: Cause races under highly-parallel
workloads (with dahdi_autoreg=0).

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
This commit is contained in:
Oron Peled 2013-09-29 16:08:35 +02:00 committed by Tzafrir Cohen
parent b4ff53c00c
commit a1a02a2997
2 changed files with 33 additions and 5 deletions

View File

@ -29,6 +29,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#ifdef PROTOCOL_DEBUG #ifdef PROTOCOL_DEBUG
#include <linux/ctype.h> #include <linux/ctype.h>
@ -913,6 +914,8 @@ static void xbus_free_ddev(xbus_t *xbus)
xbus->ddev = NULL; xbus->ddev = NULL;
} }
static DEFINE_MUTEX(dahdi_registration_mutex);
int xbus_register_dahdi_device(xbus_t *xbus) int xbus_register_dahdi_device(xbus_t *xbus)
{ {
int i; int i;
@ -920,6 +923,11 @@ int xbus_register_dahdi_device(xbus_t *xbus)
int ret; int ret;
XBUS_DBG(DEVICES, xbus, "Entering %s\n", __func__); XBUS_DBG(DEVICES, xbus, "Entering %s\n", __func__);
ret = mutex_lock_interruptible(&dahdi_registration_mutex);
if (ret < 0) {
XBUS_ERR(xbus, "dahdi_registration_mutex already taken\n");
goto err;
}
if (xbus_is_registered(xbus)) { if (xbus_is_registered(xbus)) {
XBUS_ERR(xbus, "Already registered to DAHDI\n"); XBUS_ERR(xbus, "Already registered to DAHDI\n");
WARN_ON(1); WARN_ON(1);
@ -983,30 +991,41 @@ int xbus_register_dahdi_device(xbus_t *xbus)
xpd_dahdi_postregister(xpd); xpd_dahdi_postregister(xpd);
} }
} }
return 0; ret = 0;
out:
mutex_unlock(&dahdi_registration_mutex);
return ret;
err: err:
xbus_free_ddev(xbus); xbus_free_ddev(xbus);
return ret; goto out;
} }
void xbus_unregister_dahdi_device(xbus_t *xbus) void xbus_unregister_dahdi_device(xbus_t *xbus)
{ {
int i; int i;
int ret;
XBUS_NOTICE(xbus, "%s\n", __func__); XBUS_NOTICE(xbus, "%s\n", __func__);
ret = mutex_lock_interruptible(&dahdi_registration_mutex);
if (ret < 0) {
XBUS_ERR(xbus, "dahdi_registration_mutex already taken\n");
return;
}
for (i = 0; i < MAX_XPDS; i++) { for (i = 0; i < MAX_XPDS; i++) {
xpd_t *xpd = xpd_of(xbus, i); xpd_t *xpd = xpd_of(xbus, i);
xpd_dahdi_preunregister(xpd); xpd_dahdi_preunregister(xpd);
} }
if (xbus->ddev) { if (xbus->ddev) {
dahdi_unregister_device(xbus->ddev); dahdi_unregister_device(xbus->ddev);
XBUS_NOTICE(xbus, "%s: finished dahdi_unregister_device()\n", __func__); XBUS_NOTICE(xbus, "%s: finished dahdi_unregister_device()\n",
__func__);
xbus_free_ddev(xbus); xbus_free_ddev(xbus);
} }
for (i = 0; i < MAX_XPDS; i++) { for (i = 0; i < MAX_XPDS; i++) {
xpd_t *xpd = xpd_of(xbus, i); xpd_t *xpd = xpd_of(xbus, i);
xpd_dahdi_postunregister(xpd); xpd_dahdi_postunregister(xpd);
} }
mutex_unlock(&dahdi_registration_mutex);
} }
/* /*

View File

@ -28,6 +28,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#ifdef PROTOCOL_DEBUG #ifdef PROTOCOL_DEBUG
#include <linux/ctype.h> #include <linux/ctype.h>
@ -613,6 +614,8 @@ static DEVICE_ATTR_READER(span_show, dev, buf)
return len; return len;
} }
static DEFINE_MUTEX(span_store_mutex);
/* /*
* For backward compatibility with old dahdi-tools * For backward compatibility with old dahdi-tools
* Remove after dahdi_registration is upgraded * Remove after dahdi_registration is upgraded
@ -635,6 +638,11 @@ static DEVICE_ATTR_WRITER(span_store, dev, buf, count)
XPD_DBG(DEVICES, xpd, XPD_DBG(DEVICES, xpd,
"%s -- deprecated (should use pinned-spans)\n", "%s -- deprecated (should use pinned-spans)\n",
(dahdi_reg) ? "register" : "unregister"); (dahdi_reg) ? "register" : "unregister");
ret = mutex_lock_interruptible(&span_store_mutex);
if (ret < 0) {
XBUS_ERR(xpd->xbus, "span_store_mutex already taken\n");
return ret;
}
if (xbus_is_registered(xpd->xbus)) { if (xbus_is_registered(xpd->xbus)) {
if (dahdi_reg) { if (dahdi_reg) {
XPD_DBG(DEVICES, xpd, XPD_DBG(DEVICES, xpd,
@ -652,6 +660,7 @@ static DEVICE_ATTR_WRITER(span_store, dev, buf, count)
xbus_register_dahdi_device(xpd->xbus); xbus_register_dahdi_device(xpd->xbus);
} }
} }
mutex_unlock(&span_store_mutex);
return count; return count;
} }