[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 3/9] mm: Scrub pages in alloc_heap_pages() if needed
>>> On 14.04.17 at 17:37, <boris.ostrovsky@xxxxxxxxxx> wrote: > When allocating pages in alloc_heap_pages() first look for clean pages. As expressed before, there are cases when we don't really need scrubbed pages. Hence the local variable "use_unscrubbed" below should really be some form of input to alloc_heap_pages(). > --- a/xen/common/page_alloc.c > +++ b/xen/common/page_alloc.c > @@ -700,34 +700,17 @@ static struct page_info *alloc_heap_pages( > unsigned int order, unsigned int memflags, > struct domain *d) > { > - unsigned int i, j, zone = 0, nodemask_retry = 0; > - nodeid_t first_node, node = MEMF_get_node(memflags), req_node = node; > + unsigned int i, j, zone, nodemask_retry; > + nodeid_t first_node, node, req_node; > unsigned long request = 1UL << order; > struct page_info *pg; > - nodemask_t nodemask = (d != NULL ) ? d->node_affinity : node_online_map; > - bool_t need_tlbflush = 0; > + nodemask_t nodemask; > + bool need_scrub, need_tlbflush = false, use_unscrubbed = false; > uint32_t tlbflush_timestamp = 0; > > /* Make sure there are enough bits in memflags for nodeID. */ > BUILD_BUG_ON((_MEMF_bits - _MEMF_node) < (8 * sizeof(nodeid_t))); > > - if ( node == NUMA_NO_NODE ) > - { > - if ( d != NULL ) > - { > - node = next_node(d->last_alloc_node, nodemask); > - if ( node >= MAX_NUMNODES ) > - node = first_node(nodemask); > - } > - if ( node >= MAX_NUMNODES ) > - node = cpu_to_node(smp_processor_id()); > - } > - first_node = node; > - > - ASSERT(node < MAX_NUMNODES); > - ASSERT(zone_lo <= zone_hi); > - ASSERT(zone_hi < NR_ZONES); The last two can remain where they are (but see also below). > @@ -754,6 +740,28 @@ static struct page_info *alloc_heap_pages( > tmem_freeable_pages() ) > goto try_tmem; > > + again: Is there any hope to get away without such an ugly pseudo loop? E.g. by making this function a helper function of a relatively thin wrapper named alloc_heap_pages(), invoking this helper twice unless use_unscrubbed is true (as said, this ought to be an input)? > + nodemask_retry = 0; > + nodemask = (d != NULL ) ? d->node_affinity : node_online_map; Stray blank before closing paren; you may want to consider dropping the != NULL altogether, at which point the parens won't be needed anymore (unless, of course, all the code churn here can be undone anyway). > @@ -769,8 +777,16 @@ static struct page_info *alloc_heap_pages( > > /* Find smallest order which can satisfy the request. */ > for ( j = order; j <= MAX_ORDER; j++ ) > + { > if ( (pg = page_list_remove_head(&heap(node, zone, j))) ) > - goto found; > + { > + if ( (order == 0) || use_unscrubbed || Why is order-0 a special case here? > @@ -832,6 +864,20 @@ static struct page_info *alloc_heap_pages( > if ( d != NULL ) > d->last_alloc_node = node; > > + if ( need_scrub ) > + { > + for ( i = 0; i < (1 << order); i++ ) > + { > + if ( test_bit(_PGC_need_scrub, &pg[i].count_info) ) > + { > + scrub_one_page(&pg[i]); > + pg[i].count_info &= ~PGC_need_scrub; This is pointless, which will become more obvious once you move this loop body into ... > + node_need_scrub[node]--; > + } > + } > + pg->u.free.dirty_head = false; > + } > + > for ( i = 0; i < (1 << order); i++ ) > { > /* Reference count must continuously be zero for free pages. */ ... the already existing loop here. The "pointless" part is because of pg[i].count_info = PGC_state_inuse; but of course you'd need to adjust the immediately preceding BUG_ON(). Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |