Re: [Xen-devel] [PATCH] xen/mm.h: add helper function to test-and-clear _PGC_allocated

2019-07-15 Thread Paul Durrant
> -Original Message-
> From: Jan Beulich 
> Sent: 15 July 2019 10:18
> To: Paul Durrant 
> Cc: JulienGrall ; Andrew Cooper 
> ; George Dunlap
> ; Ian Jackson ; Roger Pau 
> Monne
> ; Volodymyr Babchuk ; 
> Stefano Stabellini
> ; xen-devel@lists.xenproject.org; Konrad Rzeszutek 
> Wilk
> ; Tamas K Lengyel ; Tim 
> (Xen.org) ; Wei Liu
> 
> Subject: Re: [Xen-devel] [PATCH] xen/mm.h: add helper function to 
> test-and-clear _PGC_allocated
> 
> On 15.07.2019 10:45, Paul Durrant wrote:
> >> From: Jan Beulich 
> >> Sent: 10 July 2019 23:53
> >>
> >> On 10.07.2019 18:17, Paul Durrant wrote:
> >>> @@ -418,13 +417,7 @@ static void hvm_free_ioreq_mfn(struct 
> >>> hvm_ioreq_server *s, bool buf)
> >>>unmap_domain_page_global(iorp->va);
> >>>iorp->va = NULL;
> >>>
> >>> -/*
> >>> - * Check whether we need to clear the allocation reference before
> >>> - * dropping the explicit references taken by get_page_and_type().
> >>> - */
> >>> -if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
> >>> -put_page(page);
> >>> -
> >>> +clear_assignment_reference(page);
> >>>put_page_and_type(page);
> >>>}
> >>
> >> Is there a specific reason you drop the comment? It doesn't become
> >> less relevant than when it was added, does it?
> >
> > Not sure, since what's actually going on is now internal to the function.
> > If I change the function name to clear_allocation_reference() then I
> > think the comment probably becomes extraneous.
> 
> Well, the perspective I'm taking is that the ordering constraint
> wrt put_page_and_type() doesn't go away and is a relevant part of
> what the comment talks about.

Ok. Would you be happy fixing the comment to your taste on commit then, as I'm 
not sure exactly what you want to say?

  Paul

> 
> Jan
___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH] xen/mm.h: add helper function to test-and-clear _PGC_allocated

2019-07-15 Thread Jan Beulich
On 15.07.2019 10:45, Paul Durrant wrote:
>> From: Jan Beulich 
>> Sent: 10 July 2019 23:53
>>
>> On 10.07.2019 18:17, Paul Durrant wrote:
>>> @@ -418,13 +417,7 @@ static void hvm_free_ioreq_mfn(struct hvm_ioreq_server 
>>> *s, bool buf)
>>>unmap_domain_page_global(iorp->va);
>>>iorp->va = NULL;
>>>
>>> -/*
>>> - * Check whether we need to clear the allocation reference before
>>> - * dropping the explicit references taken by get_page_and_type().
>>> - */
>>> -if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
>>> -put_page(page);
>>> -
>>> +clear_assignment_reference(page);
>>>put_page_and_type(page);
>>>}
>>
>> Is there a specific reason you drop the comment? It doesn't become
>> less relevant than when it was added, does it?
> 
> Not sure, since what's actually going on is now internal to the function.
> If I change the function name to clear_allocation_reference() then I
> think the comment probably becomes extraneous.

Well, the perspective I'm taking is that the ordering constraint
wrt put_page_and_type() doesn't go away and is a relevant part of
what the comment talks about.

Jan
___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH] xen/mm.h: add helper function to test-and-clear _PGC_allocated

2019-07-15 Thread Paul Durrant
> -Original Message-
> From: Jan Beulich 
> Sent: 10 July 2019 23:53
> To: Paul Durrant 
> Cc: xen-devel@lists.xenproject.org; Julien Grall ; 
> Andrew Cooper
> ; Roger Pau Monne ; 
> Volodymyr Babchuk
> ; George Dunlap ; Ian 
> Jackson
> ; Stefano Stabellini ; Konrad 
> Rzeszutek Wilk
> ; Tamas K Lengyel ; Tim 
> (Xen.org) ; Wei Liu
> 
> Subject: Re: [Xen-devel] [PATCH] xen/mm.h: add helper function to 
> test-and-clear _PGC_allocated
> 
> On 10.07.2019 18:17, Paul Durrant wrote:
> > @@ -418,13 +417,7 @@ static void hvm_free_ioreq_mfn(struct hvm_ioreq_server 
> > *s, bool buf)
> >   unmap_domain_page_global(iorp->va);
> >   iorp->va = NULL;
> >
> > -/*
> > - * Check whether we need to clear the allocation reference before
> > - * dropping the explicit references taken by get_page_and_type().
> > - */
> > -if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
> > -put_page(page);
> > -
> > +clear_assignment_reference(page);
> >   put_page_and_type(page);
> >   }
> 
> Is there a specific reason you drop the comment? It doesn't become
> less relevant than when it was added, does it?

Not sure, since what's actually going on is now internal to the function. If I 
change the function name to clear_allocation_reference() then I think the 
comment probably becomes extraneous.

> 
> > --- a/xen/include/xen/mm.h
> > +++ b/xen/include/xen/mm.h
> > @@ -658,4 +658,15 @@ static inline void 
> > share_xen_page_with_privileged_guests(
> >   share_xen_page_with_guest(page, dom_xen, flags);
> >   }
> >
> > +static inline void clear_assignment_reference(struct page_info *page)
> 
> I think the function should have 'page' in it's name. Perhaps
> page_deassign() / page_dealloc() are also misleading, but how
> about page_put_alloc() or page_put_alloc_ref()?
> 

Ok, I think page_put_alloc_ref() is most descriptive (particularly w.r.t. the 
above discussion).

> > +{
> > +/*
> > + * It is unsafe to clear _PGC_allocated without holding an additional
> > + * reference.
> > + */
> > +ASSERT((page->count_info & PGC_count_mask) > 1);
> 
> While this isn't really in line with our goal of wanting to limit
> damage also in release builds, I agree that there's no really good
> alternative here. Crashing the owner of the page wouldn't help
> much, and bailing from the function wouldn't necessarily be better
> either. Hence I think this would better be BUG_ON().

Ok.

> 
> > +if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
> > +put_page(page);
> > +}
> 
> On the whole I have to admit I'm not entirely convinced the "open-
> coding" as you call it (to me it's not really open-coding as long as
> there is no helper) is such a bad thing here: Without the helper it
> is slightly more obvious at the use sites what's actually going on.
> But maybe that's indeed just me.

I still think a helper is better, but I'll add a comment to describe what it is 
doing.

  Paul

> 
> Jan

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH] xen/mm.h: add helper function to test-and-clear _PGC_allocated

2019-07-10 Thread Jan Beulich
On 10.07.2019 18:17, Paul Durrant wrote:
> @@ -418,13 +417,7 @@ static void hvm_free_ioreq_mfn(struct hvm_ioreq_server 
> *s, bool buf)
>   unmap_domain_page_global(iorp->va);
>   iorp->va = NULL;
>   
> -/*
> - * Check whether we need to clear the allocation reference before
> - * dropping the explicit references taken by get_page_and_type().
> - */
> -if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
> -put_page(page);
> -
> +clear_assignment_reference(page);
>   put_page_and_type(page);
>   }

Is there a specific reason you drop the comment? It doesn't become
less relevant than when it was added, does it?

> --- a/xen/include/xen/mm.h
> +++ b/xen/include/xen/mm.h
> @@ -658,4 +658,15 @@ static inline void share_xen_page_with_privileged_guests(
>   share_xen_page_with_guest(page, dom_xen, flags);
>   }
>   
> +static inline void clear_assignment_reference(struct page_info *page)

I think the function should have 'page' in it's name. Perhaps
page_deassign() / page_dealloc() are also misleading, but how
about page_put_alloc() or page_put_alloc_ref()?

> +{
> +/*
> + * It is unsafe to clear _PGC_allocated without holding an additional
> + * reference.
> + */
> +ASSERT((page->count_info & PGC_count_mask) > 1);

While this isn't really in line with our goal of wanting to limit
damage also in release builds, I agree that there's no really good
alternative here. Crashing the owner of the page wouldn't help
much, and bailing from the function wouldn't necessarily be better
either. Hence I think this would better be BUG_ON().

> +if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
> +put_page(page);
> +}

On the whole I have to admit I'm not entirely convinced the "open-
coding" as you call it (to me it's not really open-coding as long as
there is no helper) is such a bad thing here: Without the helper it
is slightly more obvious at the use sites what's actually going on.
But maybe that's indeed just me.

Jan

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH] xen/mm.h: add helper function to test-and-clear _PGC_allocated

2019-07-10 Thread Paul Durrant
The _PGC_allocated flag is set on a page when it is assigned to a domain
along with an initial reference count of 1. To clear this initial
reference count it is necessary to test-and-clear _PGC_allocated and then
only drop the reference if the test-and-clear succeeds. This is open-
coded in many places. It is also unsafe to test-and-clear _PGC_allocated
unless the caller holds an additional reference.

This patch adds a helper function, clear_assignment_reference(), to
replace all the open-coded test-and-clear/put_page occurrences and
incorporates in that an ASSERTion that an additional page reference is
held.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Julien Grall 
Cc: Volodymyr Babchuk 
Cc: Andrew Cooper 
Cc: George Dunlap 
Cc: Ian Jackson 
Cc: Jan Beulich 
Cc: Konrad Rzeszutek Wilk 
Cc: Tim Deegan 
Cc: Wei Liu 
Cc: "Roger Pau Monné" 
Cc: Tamas K Lengyel 
Cc: George Dunlap 
---
 xen/arch/arm/domain.c |  4 +---
 xen/arch/x86/domain.c |  3 +--
 xen/arch/x86/hvm/ioreq.c  | 11 ++-
 xen/arch/x86/mm.c |  3 +--
 xen/arch/x86/mm/mem_sharing.c |  9 +++--
 xen/arch/x86/mm/p2m-pod.c |  4 +---
 xen/arch/x86/mm/p2m.c |  3 +--
 xen/common/grant_table.c  |  3 +--
 xen/common/memory.c   |  5 ++---
 xen/common/xenoprof.c |  3 +--
 xen/include/xen/mm.h  | 11 +++
 11 files changed, 25 insertions(+), 34 deletions(-)

diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 4f44d5c742..78700d6f08 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -926,9 +926,7 @@ static int relinquish_memory(struct domain *d, struct 
page_list_head *list)
  */
 continue;
 
-if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
-put_page(page);
-
+clear_assignment_reference(page);
 put_page(page);
 
 if ( hypercall_preempt_check() )
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 147f96a09e..c8c51d5f76 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -1939,8 +1939,7 @@ static int relinquish_memory(
 BUG();
 }
 
-if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
-put_page(page);
+clear_assignment_reference(page);
 
 /*
  * Forcibly invalidate top-most, still valid page tables at this point
diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
index 7a80cfb28b..129f9fddbc 100644
--- a/xen/arch/x86/hvm/ioreq.c
+++ b/xen/arch/x86/hvm/ioreq.c
@@ -398,8 +398,7 @@ static int hvm_alloc_ioreq_mfn(struct hvm_ioreq_server *s, 
bool buf)
 return 0;
 
  fail:
-if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
-put_page(page);
+clear_assignment_reference(page);
 put_page_and_type(page);
 
 return -ENOMEM;
@@ -418,13 +417,7 @@ static void hvm_free_ioreq_mfn(struct hvm_ioreq_server *s, 
bool buf)
 unmap_domain_page_global(iorp->va);
 iorp->va = NULL;
 
-/*
- * Check whether we need to clear the allocation reference before
- * dropping the explicit references taken by get_page_and_type().
- */
-if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
-put_page(page);
-
+clear_assignment_reference(page);
 put_page_and_type(page);
 }
 
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index df2c0130f1..9fe66a6d26 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -498,8 +498,7 @@ void share_xen_page_with_guest(struct page_info *page, 
struct domain *d,
 
 void free_shared_domheap_page(struct page_info *page)
 {
-if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
-put_page(page);
+clear_assignment_reference(page);
 if ( !test_and_clear_bit(_PGC_xen_heap, &page->count_info) )
 ASSERT_UNREACHABLE();
 page->u.inuse.type_info = 0;
diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c
index f16a3f5324..7a643aed53 100644
--- a/xen/arch/x86/mm/mem_sharing.c
+++ b/xen/arch/x86/mm/mem_sharing.c
@@ -1000,8 +1000,7 @@ static int share_pages(struct domain *sd, gfn_t sgfn, 
shr_handle_t sh,
 mem_sharing_page_unlock(firstpg);
 
 /* Free the client page */
-if(test_and_clear_bit(_PGC_allocated, &cpage->count_info))
-put_page(cpage);
+clear_assignment_reference(cpage);
 put_page(cpage);
 
 /* We managed to free a domain page. */
@@ -1082,8 +1081,7 @@ int mem_sharing_add_to_physmap(struct domain *sd, 
unsigned long sgfn, shr_handle
 ret = -EOVERFLOW;
 goto err_unlock;
 }
-if ( test_and_clear_bit(_PGC_allocated, &cpage->count_info) )
-put_page(cpage);
+clear_assignment_reference(cpage);
 put_page(cpage);
 }
 }
@@ -1177,8 +1175,7 @@ int __mem_sharing_unshare_page(struct domain *d,
 domain_crash(d);