ia64/linux-2.6.18-xen.hg

changeset 717:d49054ec0cc6

gnttab: Checking ->next is insufficient to decide if something is
queued in a singly-linked list (doesn't work for final item).

From: Jake Wires <jake.wires@citrix.com>.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Oct 30 12:01:06 2008 +0000 (2008-10-30)
parents eb759c00a1f8
children ac9a6209c679
files drivers/xen/core/gnttab.c include/xen/gnttab.h
line diff
     1.1 --- a/drivers/xen/core/gnttab.c	Thu Oct 30 11:59:46 2008 +0000
     1.2 +++ b/drivers/xen/core/gnttab.c	Thu Oct 30 12:01:06 2008 +0000
     1.3 @@ -112,6 +112,7 @@ static void do_free_callbacks(void)
     1.4  		next = callback->next;
     1.5  		if (gnttab_free_count >= callback->count) {
     1.6  			callback->next = NULL;
     1.7 +			callback->queued = 0;
     1.8  			callback->fn(callback->arg);
     1.9  		} else {
    1.10  			callback->next = gnttab_free_callback_list;
    1.11 @@ -343,11 +344,12 @@ void gnttab_request_free_callback(struct
    1.12  {
    1.13  	unsigned long flags;
    1.14  	spin_lock_irqsave(&gnttab_list_lock, flags);
    1.15 -	if (callback->next)
    1.16 +	if (callback->queued)
    1.17  		goto out;
    1.18  	callback->fn = fn;
    1.19  	callback->arg = arg;
    1.20  	callback->count = count;
    1.21 +	callback->queued = 1;
    1.22  	callback->next = gnttab_free_callback_list;
    1.23  	gnttab_free_callback_list = callback;
    1.24  	check_free_callbacks();
    1.25 @@ -365,6 +367,7 @@ void gnttab_cancel_free_callback(struct 
    1.26  	for (pcb = &gnttab_free_callback_list; *pcb; pcb = &(*pcb)->next) {
    1.27  		if (*pcb == callback) {
    1.28  			*pcb = callback->next;
    1.29 +			callback->queued = 0;
    1.30  			break;
    1.31  		}
    1.32  	}
     2.1 --- a/include/xen/gnttab.h	Thu Oct 30 11:59:46 2008 +0000
     2.2 +++ b/include/xen/gnttab.h	Thu Oct 30 12:01:06 2008 +0000
     2.3 @@ -44,10 +44,11 @@
     2.4  #include <xen/features.h>
     2.5  
     2.6  struct gnttab_free_callback {
     2.7 -	struct gnttab_free_callback *next;
     2.8 +	struct list_head list;
     2.9  	void (*fn)(void *);
    2.10  	void *arg;
    2.11  	u16 count;
    2.12 +	u8 queued;
    2.13  };
    2.14  
    2.15  int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,