static int relinquish_memory(struct domain *d, struct page_list_head *list) { struct page_info *page, *tmp; int ret = 0; /* Use a recursive lock, as we may enter 'free_domheap_page'. */ spin_lock_recursive(&d->page_alloc_lock); page_list_for_each_safe( page, tmp, list ) { /* Grab a reference to the page so it won't disappear from under us. */ if ( unlikely(!get_page(page, d)) ) /* Couldn't get a reference -- someone is freeing this page. */ BUG(); if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) put_page(page); put_page(page); if ( hypercall_preempt_check() ) { ret = -ERESTART; goto out; } } out: spin_unlock_recursive(&d->page_alloc_lock); return ret; }
static int relinquish_memory(struct domain *d, struct page_list_head *list) { struct page_info *page, *tmp; int ret = 0; /* Use a recursive lock, as we may enter 'free_domheap_page'. */ spin_lock_recursive(&d->page_alloc_lock); page_list_for_each_safe( page, tmp, list ) { /* Grab a reference to the page so it won't disappear from under us. */ if ( unlikely(!get_page(page, d)) ) /* * Couldn't get a reference -- someone is freeing this page and * has already committed to doing so, so no more to do here. * * Note that the page must be left on the list, a list_del * here will clash with the list_del done by the other * party in the race and corrupt the list head. */ continue; if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) put_page(page); put_page(page); if ( hypercall_preempt_check() ) { ret = -ERESTART; goto out; } } out: spin_unlock_recursive(&d->page_alloc_lock); return ret; }
void pcidevs_lock(void) { spin_lock_recursive(&_pcidevs_lock); }