drm_lock() does:
        for (;;) {
                __set_current_state(TASK_INTERRUPTIBLE);
                ...
                if (drm_lock_take(&master->lock, lock->context)) {
                        <==== schedule() here
                        master->lock.file_priv = file_priv;
                        master->lock.lock_time = jiffies;
                        atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
                        break;  /* Got lock */
                }
                ...
        }
If a preempt occurs in marked line, the task already holds the lock but
set to interruptible, then nobody can wakeup the task (except signal) and
other tasks can't get the lock again. Am I missing anything?

Signed-off-by: Shaohua Li<shaohua...@intel.com>
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c
index e2f70a5..32fbca0 100644
--- a/drivers/gpu/drm/drm_lock.c
+++ b/drivers/gpu/drm/drm_lock.c
@@ -76,6 +76,7 @@ int drm_lock(struct drm_device *dev, void *data, struct 
drm_file *file_priv)
        master->lock.user_waiters++;
        spin_unlock_bh(&master->lock.spinlock);
 
+       preempt_disable();
        for (;;) {
                __set_current_state(TASK_INTERRUPTIBLE);
                if (!master->lock.hw_lock) {
@@ -90,18 +91,21 @@ int drm_lock(struct drm_device *dev, void *data, struct 
drm_file *file_priv)
                        atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
                        break;  /* Got lock */
                }
+               preempt_enable_no_resched();
 
                /* Contention */
                schedule();
+               preempt_disable();
                if (signal_pending(current)) {
                        ret = -EINTR;
                        break;
                }
        }
+       __set_current_state(TASK_RUNNING);
+       preempt_enable();
        spin_lock_bh(&master->lock.spinlock);
        master->lock.user_waiters--;
        spin_unlock_bh(&master->lock.spinlock);
-       __set_current_state(TASK_RUNNING);
        remove_wait_queue(&master->lock.lock_queue, &entry);
 
        DRM_DEBUG("%d %s\n", lock->context,



------------------------------------------------------------------------------
Stay on top of everything new and different, both inside and 
around Java (TM) technology - register by April 22, and save
$200 on the JavaOne (SM) conference, June 2-5, 2009, San Francisco.
300 plus technical and hands-on sessions. Register today. 
Use priority code J9JMT32. http://p.sf.net/sfu/p
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to