From: cl349@firebug.cl.cam.ac.uk Date: Mon, 22 Aug 2005 20:52:38 +0000 (+0000) Subject: Grant table updates for block device changes. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~16871^2~19 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=3c047eef3cece978cdce2ff1a250e46af3de5e4a;p=xen.git Grant table updates for block device changes. - add gnttab_free_grant_reference - make gnttab_free_grant_references interface consistent with other gnttab functions - add support for callback when references are freed Signed-off-by: Christian Limpach --- diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c index 63deb685f3..99c68ae11e 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c @@ -50,6 +50,8 @@ static grant_ref_t gnttab_free_head; static grant_entry_t *shared; +static struct gnttab_free_callback *gnttab_free_callback_list = NULL; + /* * Lock-free grant-entry allocator */ @@ -65,6 +67,16 @@ get_free_entry( return fh; } +static void do_free_callbacks(void) +{ + struct gnttab_free_callback *callback = gnttab_free_callback_list; + gnttab_free_callback_list = NULL; + while (callback) { + schedule_work(callback->work); + callback = callback->next; + } +} + static inline void put_free_entry( grant_ref_t ref) @@ -72,6 +84,8 @@ put_free_entry( grant_ref_t fh, nfh = gnttab_free_head; do { gnttab_free_list[ref] = fh = nfh; wmb(); } while ( unlikely((nfh = cmpxchg(&gnttab_free_head, fh, ref)) != fh) ); + if ( unlikely(gnttab_free_callback_list) ) + do_free_callbacks(); } /* @@ -189,17 +203,23 @@ gnttab_end_foreign_transfer( } void -gnttab_free_grant_references( u16 count, grant_ref_t head ) +gnttab_free_grant_reference( grant_ref_t ref ) +{ + + put_free_entry(ref); +} + +void +gnttab_free_grant_references( grant_ref_t *head, + grant_ref_t terminal ) { /* TODO: O(N)...? */ - grant_ref_t to_die = 0, next = head; - int i; + grant_ref_t ref; - for ( i = 0; i < count; i++ ) - { - to_die = next; - next = gnttab_free_list[next]; - put_free_entry( to_die ); + while (*head != terminal) { + ref = *head; + *head = gnttab_free_list[*head]; + put_free_entry(ref); } } @@ -244,6 +264,15 @@ gnttab_release_grant_reference( grant_ref_t *private_head, *private_head = release; } +void +gnttab_request_free_callback(struct gnttab_free_callback *callback, + struct work_struct *work) +{ + callback->work = work; + callback->next = gnttab_free_callback_list; + gnttab_free_callback_list = callback; +} + /* * ProcFS operations */ diff --git a/linux-2.6-xen-sparse/include/asm-xen/gnttab.h b/linux-2.6-xen-sparse/include/asm-xen/gnttab.h index 642a74dbf9..292652c681 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/gnttab.h +++ b/linux-2.6-xen-sparse/include/asm-xen/gnttab.h @@ -21,6 +21,13 @@ #define NR_GRANT_FRAMES 4 #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t)) +struct work_struct; + +struct gnttab_free_callback { + struct gnttab_free_callback *next; + struct work_struct *work; +}; + int gnttab_grant_foreign_access( domid_t domid, unsigned long frame, int readonly); @@ -48,9 +55,13 @@ int gnttab_alloc_grant_references( u16 count, grant_ref_t *pprivate_head, grant_ref_t *private_terminal ); +void +gnttab_free_grant_reference( + grant_ref_t ref ); + void gnttab_free_grant_references( - u16 count, grant_ref_t private_head ); + grant_ref_t *head, grant_ref_t terminal ); int gnttab_claim_grant_reference( grant_ref_t *pprivate_head, grant_ref_t terminal @@ -60,6 +71,10 @@ void gnttab_release_grant_reference( grant_ref_t *private_head, grant_ref_t release ); +void +gnttab_request_free_callback( + struct gnttab_free_callback *callback, struct work_struct *work ); + void gnttab_grant_foreign_access_ref( grant_ref_t ref, domid_t domid, unsigned long frame, int readonly);