UBI leb_write_unlock NULL pointer Oops (continuation)

Bill Pringlemeir bpringlemeir at nbsps.com
Thu Feb 20 12:38:07 EST 2014


On 20 Feb 2014, bpringlemeir at nbsps.com wrote:

> You could alter '__rwsem_do_wake',
>
> static inline struct rw_semaphore *
> __rwsem_do_wake(struct rw_semaphore *sem, int wakewrite)
> {
> 	struct rwsem_waiter *waiter;
> 	struct task_struct *tsk;
> 	int woken;
>
	waiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list);
+       if(!waiter) {
+          printk("Bad rwsem\n");
+          printk("activity is %d.\n", sem->activity);
+          BUG();
+       }
	if (waiter->type == RWSEM_WAITING_FOR_WRITE) {
		if (wakewrite)
>
> ... or something like that.
>
> * the rw-semaphore definition
> * - if activity is 0 then there are no active readers or writers
> * - if activity is +ve then that is the number of active readers
> * - if activity is -1 then there is one active writer
> * - if wait_list is not empty, then there are processes waiting...
>
> It seems inconsistent to have a non-empty list with activity as 0 as
> well?  The above is trying to trace when we find a 'NULL' in the
> 'wait_list', which always seems to be the issue, but probably not the
> root cause.
>
> You can also put similar code in '__rwsem_wake_one_writer' if you
> instead get the 'up_read()' fault.

Sorry, this code has to go in the callers before they write to
'activity'.

void __up_write(struct rw_semaphore *sem)
{
	unsigned long flags;
+	struct rwsem_waiter *waiter;


	raw_spin_lock_irqsave(&sem->wait_lock, flags);

+	waiter = list_entry(sem->wait_list.next, struct rwsem_waiter, list);
+       if(!waiter) {
+          printk("Bad rwsem\n");
+          printk("activity is %d.\n", sem->activity);
+          BUG();
+       }

	sem->activity = 0;
	if (!list_empty(&sem->wait_list))
		sem = __rwsem_do_wake(sem, 1);

	raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
}

__up_read() is the other one.  Or you wait to see if the function traces
are helpful.



More information about the linux-mtd mailing list