All of lore.kernel.org
 help / color / mirror / Atom feed
* cmpxchg broken in some situation
@ 2007-09-30 10:34 Fuxin Zhang
  2007-10-01  2:53 ` Ralf Baechle
  0 siblings, 1 reply; 14+ messages in thread
From: Fuxin Zhang @ 2007-09-30 10:34 UTC (permalink / raw)
  To: linux-mips

hi,   
   Today I run across a possible bug of cmpxchg implementation. When 
playing with DRM on our Fulong, the following function 
(drivers/char/drm/drm_lock.c) is not working correctly in 64BIT mips:
   cmpxchg failed to set *lock to new value. (return 0 with *lock unchanged)
It is probably due to type conversions between unisigned int and 
unsigned long.  When I change cmpxchg to mycmpxchg(attached below), 
problem disappeared.                                 

int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context)
{
        unsigned int old, new, prev;
        volatile unsigned int *lock = &lock_data->hw_lock->lock;

        spin_lock(&lock_data->spinlock);
        if (lock_data->kernel_waiters != 0) {
                drm_lock_transfer(lock_data, 0);
                lock_data->idle_has_lock = 1;
                spin_unlock(&lock_data->spinlock);
                return 1;
        }
        spin_unlock(&lock_data->spinlock);

        do {
                old = *lock;
                new = _DRM_LOCKING_CONTEXT(old);
                prev = cmpxchg(lock, old, new);
        } while (prev != old);

        if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != 
context) {
                DRM_ERROR("%d freed heavyweight lock held by %d\n",
                          context, _DRM_LOCKING_CONTEXT(old));
                return 1;
        }
        wake_up_interruptible(&lock_data->lock_queue);
        return 0;
}

static inline unsigned int mycmpxchg(volatile int * m, unsigned int old,
        unsigned int new)  //unsigned long to unsigned int
{
        __u32 retval;

        __asm__ __volatile__(
                        "       .set    
push                                    \n"
                        "       .set    
noat                                    \n"
                        "       .set    
mips3                                   \n"
                        "1:     ll      %0, %2                  # 
__mycmpxchg_u32       \n"
                        "       bne     %0, %z3, 
2f                             \n"
                        "       .set    
mips0                                   \n"
                        "       move    $1, 
%z4                                 \n"
                        "       .set    
mips3                                   \n"
                        "       sc      $1, 
%1                                  \n"
                        "       beqz    $1, 
3f                                  \n"
                        
"2:                                                     \n"
                        "       .subsection 
2                                   \n"
                        "3:     b       
1b                                      \n"
                        "       
.previous                                       \n"
                        "       .set    
pop                                     \n"
                        : "=&r" (retval), "=R" (*m)
                        : "R" (*m), "Jr" (old), "Jr" (new)
                        : "memory");

        smp_llsc_mb();

        return retval;
}

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2007-10-02 23:15 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-09-30 10:34 cmpxchg broken in some situation Fuxin Zhang
2007-10-01  2:53 ` Ralf Baechle
2007-10-01  3:56   ` David Daney
2007-10-01  3:59     ` David Daney
2007-10-01 10:24       ` Ralf Baechle
2007-10-01 15:11   ` Fuxin Zhang
2007-10-01 15:26     ` Ralf Baechle
2007-10-02  9:34       ` Fuxin Zhang
2007-10-02 10:35         ` Ralf Baechle
2007-10-02 14:22           ` Thiemo Seufer
2007-10-02 23:15             ` Ralf Baechle
2007-10-02 22:48           ` Fuxin Zhang
2007-10-02 22:52             ` Ralf Baechle
2007-10-02 23:07               ` Fuxin Zhang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.