mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
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 <Christian.Limpach@cl.cam.ac.uk>
This commit is contained in:
1 parent
279198e896
commit
3c047eef3c
2 files changed
+53
-9
No files matched your search
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||