[dahdi-commits] dahdi/linux.git branch "master" updated.

SVN commits to the DAHDI project dahdi-commits at lists.digium.com
Tue May 27 06:08:14 CDT 2014


branch "master" has been updated
       via  cbe92363ea76571e0d0df8a96c2715817efc3159 (commit)
       via  43a3dbb484f7715132b7ff14c846fd133831831a (commit)
       via  9a00fc6321d48444e586e84bd6cee012744731e9 (commit)
       via  db07e1b74dc42d8670c8ced10ba992ea3fb342b2 (commit)
       via  235d530fee92d4e93b24d71aafad4e5a366daa9f (commit)
       via  dfa7304f515509555866cb877eb3f6a618b9f211 (commit)
       via  08127e14f7d82a8ae0a18773fcd608f55ad6cf2e (commit)
      from  6e2698f4c1ce55818a16e5d1ef5c6ba27d63c3ea (commit)

Summary of changes:
 drivers/dahdi/xpp/card_fxs.c   |    4 +--
 drivers/dahdi/xpp/xbus-core.c  |   55 ++++++++++++++++++++++++++++++----------
 drivers/dahdi/xpp/xbus-sysfs.c |    8 ++++--
 drivers/dahdi/xpp/xpp_dahdi.c  |   20 ++++++---------
 drivers/dahdi/xpp/xpp_usb.c    |    9 ++++---
 5 files changed, 64 insertions(+), 32 deletions(-)


- Log -----------------------------------------------------------------
commit cbe92363ea76571e0d0df8a96c2715817efc3159
Author: Oron Peled <oron.peled at xorcom.com>
Date:   Mon May 12 11:36:16 2014 -0400

    xpp: re-organize calls so worker_reset()
    
    re-organize calls so worker_reset() isn't called twice
    (was called from xbus_disconnect() and worker_destroy())
    
    Signed-off-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>

diff --git a/drivers/dahdi/xpp/xbus-core.c b/drivers/dahdi/xpp/xbus-core.c
index c74cf29..5346497 100644
--- a/drivers/dahdi/xpp/xbus-core.c
+++ b/drivers/dahdi/xpp/xbus-core.c
@@ -1238,13 +1238,15 @@ static void worker_reset(xbus_t *xbus)
 	spin_unlock_irqrestore(&worker->worker_lock, flags);
 }
 
+/*
+ * Called only after worker_reset(xbus)
+ */
 static void worker_destroy(xbus_t *xbus)
 {
 	struct xbus_workqueue *worker;
 
 	BUG_ON(!xbus);
 	worker = &xbus->worker;
-	worker_reset(xbus);
 	XBUS_DBG(DEVICES, xbus, "Waiting for worker to finish...\n");
 	down(&worker->running_initialization);
 	XBUS_DBG(DEVICES, xbus, "Waiting for worker to finish -- done\n");
@@ -1297,6 +1299,7 @@ static int worker_run(xbus_t *xbus)
 	}
 	return 1;
 err:
+	worker_reset(xbus);
 	worker_destroy(xbus);
 	return 0;
 }
@@ -1464,6 +1467,7 @@ void xbus_disconnect(xbus_t *xbus)
 	del_timer_sync(&xbus->command_timer);
 	transportops_put(xbus);
 	transport_destroy(xbus);
+	/* worker_reset(xbus) was called in xbus_deactivate(xbus) */
 	worker_destroy(xbus);
 	XBUS_DBG(DEVICES, xbus, "Deactivated refcount_xbus=%d\n",
 		 refcount_xbus(xbus));

commit 43a3dbb484f7715132b7ff14c846fd133831831a
Author: Oron Peled <oron.peled at xorcom.com>
Date:   Mon May 12 11:36:16 2014 -0400

    xpp: demote some NOTICE() to DBG()
    
    Signed-off-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>

diff --git a/drivers/dahdi/xpp/card_fxs.c b/drivers/dahdi/xpp/card_fxs.c
index ce36640..2de479e 100644
--- a/drivers/dahdi/xpp/card_fxs.c
+++ b/drivers/dahdi/xpp/card_fxs.c
@@ -1957,7 +1957,7 @@ static DEVICE_ATTR_WRITER(fxs_ring_registers_store, dev, buf, count)
 				regno);
 			goto invalid_input;
 		}
-		XPD_INFO(xpd, "%s Indirect 0x%X <=== 0x%X 0x%X\n",
+		XPD_DBG(SIGNAL, xpd, "%s Indirect 0x%X <=== 0x%X 0x%X\n",
 			rtype_name, regno, h_val, l_val);
 	} else {
 		if (ret != 3) {
@@ -1968,7 +1968,7 @@ static DEVICE_ATTR_WRITER(fxs_ring_registers_store, dev, buf, count)
 		}
 		l_val = h_val;
 		h_val = 0;
-		XPD_INFO(xpd, "%s Direct 0x%X <=== 0x%X\n",
+		XPD_DBG(SIGNAL, xpd, "%s Direct 0x%X <=== 0x%X\n",
 			rtype_name, regno, h_val);
 	}
 	spin_lock_irqsave(&xpd->lock, flags);
diff --git a/drivers/dahdi/xpp/xbus-core.c b/drivers/dahdi/xpp/xbus-core.c
index f17119d..c74cf29 100644
--- a/drivers/dahdi/xpp/xbus-core.c
+++ b/drivers/dahdi/xpp/xbus-core.c
@@ -199,7 +199,7 @@ static void xbus_destroy(struct kref *kref)
 	int num;
 
 	xbus = kref_to_xbus(kref);
-	XBUS_NOTICE(xbus, "%s\n", __func__);
+	XBUS_DBG(DEVICES, xbus, "%s\n", __func__);
 	num = xbus->num;
 	xbuses_array[num].shutting_down = 1;
 	xbus_sysfs_remove(xbus);
@@ -1066,7 +1066,7 @@ void xbus_unregister_dahdi_device(xbus_t *xbus)
 	int i;
 	int ret;
 
-	XBUS_NOTICE(xbus, "%s\n", __func__);
+	XBUS_DBG(DEVICES, xbus, "%s\n", __func__);
 	ret = mutex_lock_interruptible(&dahdi_registration_mutex);
 	if (ret < 0) {
 		XBUS_ERR(xbus, "dahdi_registration_mutex already taken\n");
@@ -1085,8 +1085,8 @@ void xbus_unregister_dahdi_device(xbus_t *xbus)
 	}
 	if (xbus->ddev) {
 		dahdi_unregister_device(xbus->ddev);
-		XBUS_NOTICE(xbus, "%s: finished dahdi_unregister_device()\n",
-			    __func__);
+		XBUS_DBG(DEVICES, xbus,
+			"%s: finished dahdi_unregister_device()\n", __func__);
 		xbus_free_ddev(xbus);
 	}
 	for (i = 0; i < MAX_XPDS; i++) {
@@ -1220,8 +1220,7 @@ static void worker_reset(xbus_t *xbus)
 	name = (xbus) ? xbus->busname : "detached";
 	DBG(DEVICES, "%s\n", name);
 	if (!worker->xpds_init_done) {
-		NOTICE("%s: worker(%s)->xpds_init_done=%d\n", __func__, name,
-		       worker->xpds_init_done);
+		XBUS_NOTICE(xbus, "XPDS initialization was not finished\n");
 	}
 	spin_lock_irqsave(&worker->worker_lock, flags);
 	list_for_each_safe(card, next_card, &worker->card_list) {
diff --git a/drivers/dahdi/xpp/xpp_dahdi.c b/drivers/dahdi/xpp/xpp_dahdi.c
index 3e54ca2..8e6523d 100644
--- a/drivers/dahdi/xpp/xpp_dahdi.c
+++ b/drivers/dahdi/xpp/xpp_dahdi.c
@@ -476,7 +476,7 @@ int phonedev_alloc_channels(xpd_t *xpd, int channels)
 	int old_channels = phonedev->channels;
 	unsigned int x;
 
-	XPD_NOTICE(xpd, "Reallocating channels: %d -> %d\n",
+	XPD_DBG(DEVICES, xpd, "Reallocating channels: %d -> %d\n",
 			old_channels, channels);
 	phonedev_cleanup(xpd);
 	phonedev->channels = channels;

commit 9a00fc6321d48444e586e84bd6cee012744731e9
Author: Oron Peled <oron.peled at xorcom.com>
Date:   Mon May 12 10:51:59 2014 -0400

    xpp: stability -- better xbus shut down
    
    * Maintain a "shutting_down" flag per-xbus
    * Use it to prevent xbus dereferencing (via xbus_get()/xbus_put())
      during an xbus shutdown.
    * Also, remove xbus from global array earlier.
    
    Signed-off-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>

diff --git a/drivers/dahdi/xpp/xbus-core.c b/drivers/dahdi/xpp/xbus-core.c
index e9c6722..f17119d 100644
--- a/drivers/dahdi/xpp/xbus-core.c
+++ b/drivers/dahdi/xpp/xbus-core.c
@@ -80,8 +80,14 @@ static struct proc_dir_entry *proc_xbuses;
 
 static struct xbus_desc {
 	xbus_t *xbus;
+	int shutting_down;
 } xbuses_array[MAX_BUSES];
 
+static int xbus_is_shutting_down(int num)
+{
+	return xbuses_array[num].shutting_down;
+}
+
 static xbus_t *xbus_byhwid(const char *hwid)
 {
 	int i;
@@ -149,6 +155,8 @@ static void init_xbus(uint num, xbus_t *xbus)
 	BUG_ON(num >= ARRAY_SIZE(xbuses_array));
 	desc = &xbuses_array[num];
 	desc->xbus = xbus;
+	if (xbus)
+		desc->shutting_down = 0;
 }
 
 xbus_t *xbus_num(uint num)
@@ -188,9 +196,12 @@ static void finalize_xbuses_array(void)
 static void xbus_destroy(struct kref *kref)
 {
 	xbus_t *xbus;
+	int num;
 
 	xbus = kref_to_xbus(kref);
 	XBUS_NOTICE(xbus, "%s\n", __func__);
+	num = xbus->num;
+	xbuses_array[num].shutting_down = 1;
 	xbus_sysfs_remove(xbus);
 }
 
@@ -199,6 +210,11 @@ xbus_t *get_xbus(const char *msg, uint num)
 	unsigned long flags;
 	xbus_t *xbus;
 
+	if (xbus_is_shutting_down(num)) {
+		DBG(DEVICES, "%s(%s): XBUS-%d: shutting down\n", __func__,
+				msg, num);
+		return NULL;
+	}
 	spin_lock_irqsave(&xbuses_lock, flags);
 	xbus = xbus_num(num);
 	if (xbus != NULL) {
@@ -212,6 +228,13 @@ xbus_t *get_xbus(const char *msg, uint num)
 
 void put_xbus(const char *msg, xbus_t *xbus)
 {
+	if (xbus_is_shutting_down(xbus->num)) {
+		if (!refcount_xbus(xbus)) {
+			DBG(DEVICES, "%s(%s): XBUS-%d: shutting down\n",
+					__func__, msg, xbus->num);
+			return;
+		}
+	}
 	XBUS_DBG(DEVICES, xbus, "%s: refcount_xbus=%d\n", msg,
 		 refcount_xbus(xbus));
 	kref_put(&xbus->kref, xbus_destroy);
@@ -561,6 +584,14 @@ static void receive_tasklet_func(unsigned long data)
 void xbus_receive_xframe(xbus_t *xbus, xframe_t *xframe)
 {
 	BUG_ON(!xbus);
+	if (xbus_is_shutting_down(xbus->num)) {
+		static int rate_limit;
+
+		if ((rate_limit++ % 1000) == 0)
+			XBUS_NOTICE(xbus, "%s: during shutdown (%d)\n",
+					__func__, rate_limit);
+		return;
+	}
 	if (rx_tasklet) {
 		xframe_enqueue_recv(xbus, xframe);
 	} else {
@@ -1483,6 +1514,7 @@ void xbus_free(xbus_t *xbus)
 	num = xbus->num;
 	BUG_ON(!xbuses_array[num].xbus);
 	BUG_ON(xbus != xbuses_array[num].xbus);
+	init_xbus(num, NULL);
 	spin_unlock_irqrestore(&xbuses_lock, flags);
 #ifdef CONFIG_PROC_FS
 	if (xbus->proc_xbus_dir) {
@@ -1509,7 +1541,6 @@ void xbus_free(xbus_t *xbus)
 #endif
 	spin_lock_irqsave(&xbuses_lock, flags);
 	XBUS_DBG(DEVICES, xbus, "Going to free...\n");
-	init_xbus(num, NULL);
 	spin_unlock_irqrestore(&xbuses_lock, flags);
 	KZFREE(xbus);
 }

commit db07e1b74dc42d8670c8ced10ba992ea3fb342b2
Author: Oron Peled <oron.peled at xorcom.com>
Date:   Mon May 12 10:10:50 2014 -0400

    xpp: stability -- deadlock in waitfor_xpds()
    
    waitfor_xpds xbus sysfs file should not take an xbus refcount:
    
    * It is called from sysfs which maintain its own device refcount.
    * If put_xbus() calls xbus_destroy() than down the call chain it will
      try to release an object that is held by sysfs.
    * This will create a deadlock.
    
    Signed-off-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>

diff --git a/drivers/dahdi/xpp/xbus-core.c b/drivers/dahdi/xpp/xbus-core.c
index 5671618..e9c6722 100644
--- a/drivers/dahdi/xpp/xbus-core.c
+++ b/drivers/dahdi/xpp/xbus-core.c
@@ -1640,10 +1640,6 @@ int waitfor_xpds(xbus_t *xbus, char *buf)
 	 * FIXME: worker is created before ?????
 	 * So by now it exists and initialized.
 	 */
-	/* until end of waitfor_xpds_show(): */
-	xbus = get_xbus(__func__, xbus->num);
-	if (!xbus)
-		return -ENODEV;
 	worker = &xbus->worker;
 	BUG_ON(!worker);
 	if (!worker->wq) {
@@ -1682,7 +1678,6 @@ int waitfor_xpds(xbus_t *xbus, char *buf)
 		spin_unlock_irqrestore(&xbus->lock, flags);
 	}
 out:
-	put_xbus(__func__, xbus);	/* from start of waitfor_xpds_show() */
 	return len;
 }
 

commit 235d530fee92d4e93b24d71aafad4e5a366daa9f
Author: Oron Peled <oron.peled at xorcom.com>
Date:   Mon May 12 10:09:22 2014 -0400

    xpp: stability -- better debug information
    
    Signed-off-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>

diff --git a/drivers/dahdi/xpp/xbus-sysfs.c b/drivers/dahdi/xpp/xbus-sysfs.c
index c92ccb7..af94c3a 100644
--- a/drivers/dahdi/xpp/xbus-sysfs.c
+++ b/drivers/dahdi/xpp/xbus-sysfs.c
@@ -30,6 +30,7 @@
 #include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/delay.h>	/* for msleep() to debug */
+#include <linux/sched.h>
 #include "xpd.h"
 #include "xpp_dahdi.h"
 #include "xbus-core.h"
@@ -967,10 +968,13 @@ void xbus_sysfs_remove(xbus_t *xbus)
 	struct device *astribank;
 
 	BUG_ON(!xbus);
-	XBUS_DBG(DEVICES, xbus, "\n");
 	astribank = &xbus->astribank;
-	if (!dev_get_drvdata(astribank))
+	if (!dev_get_drvdata(astribank)) {
+		XBUS_NOTICE(xbus, "%s: already removed\n", __func__);
 		return;
+	}
+	XBUS_DBG(DEVICES, xbus, "going to unregister: refcount=%d\n",
+		atomic_read(&astribank->kobj.kref.refcount));
 	BUG_ON(dev_get_drvdata(astribank) != xbus);
 	device_unregister(astribank);
 	dev_set_drvdata(astribank, NULL);

commit dfa7304f515509555866cb877eb3f6a618b9f211
Author: Oron Peled <oron.peled at xorcom.com>
Date:   Mon May 12 10:04:28 2014 -0400

    xpp: stability -- cleaner xpp_open/close
    
     * No need to use spinlock.
     * Just correctly use the atomic open_counter.
    
    Signed-off-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>

diff --git a/drivers/dahdi/xpp/xpp_dahdi.c b/drivers/dahdi/xpp/xpp_dahdi.c
index c0e441a..3e54ca2 100644
--- a/drivers/dahdi/xpp/xpp_dahdi.c
+++ b/drivers/dahdi/xpp/xpp_dahdi.c
@@ -722,7 +722,7 @@ int xpp_open(struct dahdi_chan *chan)
 	xpd_t *xpd;
 	xbus_t *xbus;
 	int pos;
-	unsigned long flags;
+	int open_counter;
 
 	if (!chan) {
 		NOTICE("open called on a null chan\n");
@@ -743,11 +743,9 @@ int xpp_open(struct dahdi_chan *chan)
 		LINE_NOTICE(xpd, pos, "Cannot open -- device not ready\n");
 		return -ENODEV;
 	}
-	spin_lock_irqsave(&xbus->lock, flags);
-	atomic_inc(&PHONEDEV(xpd).open_counter);
+	open_counter = atomic_inc_return(&PHONEDEV(xpd).open_counter);
 	LINE_DBG(DEVICES, xpd, pos, "%s[%d]: open_counter=%d\n", current->comm,
-		 current->pid, atomic_read(&PHONEDEV(xpd).open_counter));
-	spin_unlock_irqrestore(&xbus->lock, flags);
+		 current->pid, open_counter);
 	if (PHONE_METHOD(card_open, xpd))
 		CALL_PHONE_METHOD(card_open, xpd, pos);
 	return 0;
@@ -757,17 +755,15 @@ EXPORT_SYMBOL(xpp_open);
 int xpp_close(struct dahdi_chan *chan)
 {
 	xpd_t *xpd = chan->pvt;
-	xbus_t *xbus = xpd->xbus;
 	int pos = chan->chanpos - 1;
-	unsigned long flags;
+	int open_counter;
 
-	spin_lock_irqsave(&xbus->lock, flags);
-	spin_unlock_irqrestore(&xbus->lock, flags);
 	if (PHONE_METHOD(card_close, xpd))
 		CALL_PHONE_METHOD(card_close, xpd, pos);
+	/* from xpp_open(): */
+	open_counter = atomic_dec_return(&PHONEDEV(xpd).open_counter);
 	LINE_DBG(DEVICES, xpd, pos, "%s[%d]: open_counter=%d\n", current->comm,
-		 current->pid, atomic_read(&PHONEDEV(xpd).open_counter));
-	atomic_dec(&PHONEDEV(xpd).open_counter);	/* from xpp_open() */
+		 current->pid, open_counter);
 	return 0;
 }
 EXPORT_SYMBOL(xpp_close);

commit 08127e14f7d82a8ae0a18773fcd608f55ad6cf2e
Author: Oron Peled <oron.peled at xorcom.com>
Date:   Mon May 12 10:02:35 2014 -0400

    xpp: stability fixes - xusb mutex
    
     * Replace old semaphore with mutex
     * Use this mutex for BOTH usb probe/disconnect
    
    Signed-off-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>

diff --git a/drivers/dahdi/xpp/xpp_usb.c b/drivers/dahdi/xpp/xpp_usb.c
index 8ad2b9c..7d49f1c 100644
--- a/drivers/dahdi/xpp/xpp_usb.c
+++ b/drivers/dahdi/xpp/xpp_usb.c
@@ -211,7 +211,7 @@ static xusb_t *xusb_array[MAX_BUSES] = { };
 static unsigned bus_count;
 
 /* prevent races between open() and disconnect() */
-static DEFINE_SEMAPHORE(disconnect_sem);
+static DEFINE_MUTEX(protect_xusb_devices);
 
 /*
  * AsteriskNow kernel has backported the "lean" callback from 2.6.20
@@ -652,6 +652,7 @@ static int xusb_probe(struct usb_interface *interface,
 		    iface_desc->desc.bInterfaceNumber, model_info->iface_num);
 		return -ENODEV;
 	}
+	mutex_lock(&protect_xusb_devices);
 	if ((retval = usb_reset_device(udev)) < 0) {
 		ERR("usb_reset_device failed: %d\n", retval);
 		goto probe_failed;
@@ -759,6 +760,7 @@ static int xusb_probe(struct usb_interface *interface,
 	for (i = 0; i < 10; i++)
 		xusb_listen(xusb);
 	xbus_connect(xbus);
+	mutex_unlock(&protect_xusb_devices);
 	return retval;
 probe_failed:
 	ERR("Failed to initialize xpp usb bus: %d\n", retval);
@@ -785,6 +787,7 @@ probe_failed:
 		ERR("Calling xbus_disconnect()\n");
 		xbus_disconnect(xbus);	// Blocking until fully deactivated!
 	}
+	mutex_unlock(&protect_xusb_devices);
 	return retval;
 }
 
@@ -810,7 +813,7 @@ static void xusb_disconnect(struct usb_interface *interface)
 	DBG(DEVICES, "CALLED on interface #%d\n",
 	    iface_desc->desc.bInterfaceNumber);
 	/* prevent races with open() */
-	down(&disconnect_sem);
+	mutex_lock(&protect_xusb_devices);
 
 	xusb = usb_get_intfdata(interface);
 	usb_set_intfdata(interface, NULL);
@@ -844,7 +847,7 @@ static void xusb_disconnect(struct usb_interface *interface)
 	XUSB_INFO(xusb, "now disconnected\n");
 	KZFREE(xusb);
 
-	up(&disconnect_sem);
+	mutex_unlock(&protect_xusb_devices);
 }
 
 static void xpp_send_callback(USB_PASS_CB(urb))

-----------------------------------------------------------------------


-- 
dahdi/linux.git



More information about the dahdi-commits mailing list