The patch number 9264 was added via [EMAIL PROTECTED]
to http://linuxtv.org/hg/v4l-dvb master development tree.

Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel

If anyone has any objections, please let us know by sending a message to:
        [EMAIL PROTECTED]

------

From: Darron Broad  <[EMAIL PROTECTED]>
MFE: bugfix: multi-frontend mutual exclusion parallel open


When moving from one frontend to another
an application could spawn multiple threads opening
the same new frontend and in some circumstances all of
these could become delayed waiting for the previous
frontend readers or previous frontend writer thread to
complete.

In this scenario the first thread will succeed on open
to bring the new frontend online but any others will return
EBUSY. This is a fault.  If the first succeeds and all others
are on the same frontend then they should succeed also.

Priority: normal

Signed-off-by: Darron Broad <[EMAIL PROTECTED]>
Signed-off-by: Steven Toth <[EMAIL PROTECTED]>


---

 linux/drivers/media/dvb/dvb-core/dvb_frontend.c |   51 +++++++++-------
 1 file changed, 29 insertions(+), 22 deletions(-)

diff -r 4663515ca9bc -r 2f799fe4c6bd 
linux/drivers/media/dvb/dvb-core/dvb_frontend.c
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c   Thu Oct 16 19:31:56 
2008 -0400
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c   Wed Oct 15 17:37:59 
2008 +0100
@@ -1825,39 +1825,46 @@ static int dvb_frontend_open(struct inod
        struct dvb_frontend *fe = dvbdev->priv;
        struct dvb_frontend_private *fepriv = fe->frontend_priv;
        struct dvb_adapter *adapter = fe->dvb;
-       struct dvb_device *mfedev;
-       struct dvb_frontend *mfe;
-       struct dvb_frontend_private *mfepriv;
-       int mferetry;
        int ret;
 
        dprintk ("%s\n", __func__);
 
        if (adapter->mfe_shared) {
                mutex_lock (&adapter->mfe_lock);
-               if (adapter->mfe_dvbdev != dvbdev) {
-                       if (adapter->mfe_dvbdev) {
+
+               if (adapter->mfe_dvbdev == NULL)
+                       adapter->mfe_dvbdev = dvbdev;
+
+               else if (adapter->mfe_dvbdev != dvbdev) {
+                       struct dvb_device
+                               *mfedev = adapter->mfe_dvbdev;
+                       struct dvb_frontend
+                               *mfe = mfedev->priv;
+                       struct dvb_frontend_private
+                               *mfepriv = mfe->frontend_priv;
+                       int mferetry = (dvb_mfe_wait_time << 1);
+
+                       mutex_unlock (&adapter->mfe_lock);
+                       while (mferetry-- && (mfedev->users != -1 ||
+                                       mfepriv->thread != NULL)) {
+                               if(msleep_interruptible(500)) {
+                                       if(signal_pending(current))
+                                               return -EINTR;
+                               }
+                       }
+
+                       mutex_lock (&adapter->mfe_lock);
+                       if(adapter->mfe_dvbdev != dvbdev) {
                                mfedev = adapter->mfe_dvbdev;
                                mfe = mfedev->priv;
                                mfepriv = mfe->frontend_priv;
-                               mutex_unlock (&adapter->mfe_lock);
-                               mferetry = (dvb_mfe_wait_time << 1);
-                               while (mferetry-- && (mfedev->users != -1 || 
mfepriv->thread != NULL)) {
-                                       if(msleep_interruptible(500)) {
-                                               if(signal_pending(current))
-                                                       return -EINTR;
-                                       }
+                               if (mfedev->users != -1 ||
+                                               mfepriv->thread != NULL) {
+                                       mutex_unlock (&adapter->mfe_lock);
+                                       return -EBUSY;
                                }
-                               mutex_lock (&adapter->mfe_lock);
-                               mfedev = adapter->mfe_dvbdev;
-                               mfe = mfedev->priv;
-                               mfepriv = mfe->frontend_priv;
-                               if (mfedev->users != -1 || mfepriv->thread != 
NULL) {
-                                       ret = -EBUSY;
-                                       goto err0;
-                               }
+                               adapter->mfe_dvbdev = dvbdev;
                        }
-                       adapter->mfe_dvbdev = dvbdev;
                }
        }
 


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/2f799fe4c6bd94dd86c71370d520a7b53fba082f

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to