/* Ordered by sem->wait_lock against rwsem_mark_wake(). */
                        break;
                }
-               schedule();
+               schedule_preempt_disabled();
                lockevent_inc(rwsem_sleep_reader);
        }
 
  */
 static inline int __down_read_common(struct rw_semaphore *sem, int state)
 {
+       int ret = 0;
        long count;
 
+       preempt_disable();
        if (!rwsem_read_trylock(sem, &count)) {
-               if (IS_ERR(rwsem_down_read_slowpath(sem, count, state)))
-                       return -EINTR;
+               if (IS_ERR(rwsem_down_read_slowpath(sem, count, state))) {
+                       ret = -EINTR;
+                       goto out;
+               }
                DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem);
        }
-       return 0;
+out:
+       preempt_enable();
+       return ret;
 }
 
 static inline void __down_read(struct rw_semaphore *sem)
 
 static inline int __down_read_trylock(struct rw_semaphore *sem)
 {
+       int ret = 0;
        long tmp;
 
        DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem);
 
+       preempt_disable();
        tmp = atomic_long_read(&sem->count);
        while (!(tmp & RWSEM_READ_FAILED_MASK)) {
                if (atomic_long_try_cmpxchg_acquire(&sem->count, &tmp,
                                                    tmp + RWSEM_READER_BIAS)) {
                        rwsem_set_reader_owned(sem);
-                       return 1;
+                       ret = 1;
+                       break;
                }
        }
-       return 0;
+       preempt_enable();
+       return ret;
 }
 
 /*
        DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem);
        DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem);
 
+       preempt_disable();
        rwsem_clear_reader_owned(sem);
        tmp = atomic_long_add_return_release(-RWSEM_READER_BIAS, &sem->count);
        DEBUG_RWSEMS_WARN_ON(tmp < 0, sem);
                clear_nonspinnable(sem);
                rwsem_wake(sem);
        }
+       preempt_enable();
 }
 
 /*
 {
        might_sleep();
        __down_read(sem);
+       /*
+        * The owner value for a reader-owned lock is mostly for debugging
+        * purpose only and is not critical to the correct functioning of
+        * rwsem. So it is perfectly fine to set it in a preempt-enabled
+        * context here.
+        */
        __rwsem_set_reader_owned(sem, NULL);
 }
 EXPORT_SYMBOL(down_read_non_owner);