From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: Jan Beulich <JBeulich@suse.com>
Cc: keir@xen.org, andrew.cooper3@citrix.com,
dario.faggioli@citrix.com, tim@xen.org, xen-devel@lists.xen.org,
Konrad Rzeszutek Wilk <konrad@kernel.org>,
malcolm.crossley@citrix.com
Subject: Re: [PATCH v3] Xen: Spread boot time page scrubbing across all available CPU's
Date: Mon, 14 Apr 2014 11:04:02 -0400 [thread overview]
Message-ID: <20140414150402.GE23371@phenom.dumpdata.com> (raw)
In-Reply-To: <534BC8FE0200007800008540@nat28.tlf.novell.com>
. snip.. [agreed to the comments]
> > - spin_lock(&heap_lock);
> > + region[i].rem = rem;
> > + region[i].per_cpu_sz /= cpumask_weight(&all_worker_cpus);
> > + max_per_cpu_sz = region[i].per_cpu_sz;
> > + if ( max_per_cpu_sz && chunk_size > max_per_cpu_sz )
> > + chunk_size = max_per_cpu_sz;
>
> So you may end up limiting chunk size further on each iteration.
> That's surely not very efficient.
Tim also raised this. I think a better option would be to
stash the 'chunk_size' then in the 'region' and have each
NODE worker select the most optimal value.
That will require making the loop that kicks off all the CPUs to not
increment 'chunk' based on the 'chunk size'
chunk = 0; chunk < max_per_cpu_sz; chunk += chunk_size
^^^^^^^^^^
but on a different value. Perhaps just make it a max iteration value:
j = 0; j < max_per_cpu_size / opt_bootscrub_chunk; j++
and each NOED worker will be given as 'offset' the 'j' value and can
figure out whether:
r->start + r->offset * r->per_cpu_sz >= r->end;
return
else
do the work
(and we would add 'end' in the new region).
>
> > + cpumask_copy(®ion[i].cpu, &all_worker_cpus);
> >
> > - /* Re-check page status with lock held. */
> > - if ( page_state_is(pg, free) )
> > - scrub_one_page(pg);
> > + for ( offset = 0; offset < max_per_cpu_sz; offset += chunk_size )
> > + {
> > + region[i].offset = offset;
> >
> > - spin_unlock(&heap_lock);
> > - }
> > + process_pending_softirqs();
> > +
> > + spin_lock(&heap_lock);
> > + on_selected_cpus(&all_worker_cpus, smp_scrub_heap_pages, ®ion[i], 1);
>
> So in round 2 you're telling all CPUs to scrub one node's memory. That
> ought to be particularly inefficient when you have relatively many
> CPUs and relatively little memory on the node. In the hope that nodes
Aha! I knew I missed one case.
> without CPUs aren't that common (or are relatively symmetric in terms
> of their count relative to the count of nodes with CPUs), wouldn't it be
> better (and yielding simpler code) to have each CPU scrub one such
> node in its entirety (ultimately, if this turns out to be a more common
> case, node distance could even be taken into consideration when
> picking which CPU does what).
That would work too. The non-CPU-full-NUMA case is an oddity that I have only
reproduced if I use 'numa=fake=8' on a single socket machine. In that case
the 1st node has all of the CPUs and the rest are without. And it made it faster
to just use all of the available CPU cores on the rest of the nodes.
Perhaps a check:
(end - start) < opt_bootscrub_chunk * 2
If the amount of memory per node is less than bootscrub chunk size (assume it is in
bytes) times two per then use just one CPU.
But if it is larger, then split the amount of _all_worker_cpus_ by the
total count of nodes - and have them work in lock-step? Something like this:
node = 0;
non-cpu-nodes = 0;
for_each_online_node(node)
{
if ( cpumask_empty(&node_cpus) )
non-cpu-nodes ++;
}
cnt = cpumask_weight(&all_worker_cpus) / non-cpu-nodes;
for (node = 0, i = 0; i < cpumask_weight(&all_worker_cpus); i++)
{
cpumask_clear(&r->cpus[node]);
for (j = i; j < cnt + i; j++)
cpumask_set(&r->cpus[node], j);
/* Take care to deal with SMT threads. */
}
then we would have just a subset of CPUs hammering on the non-CPU-nodes.
P.S.
I don't know of any real-life scenarios where there are NUMA nodes without
CPUs.
>
> Jan
next prev parent reply other threads:[~2014-04-14 15:04 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-11 18:08 [PATCH v3] Xen: Spread boot time page scrubbing across all available CPUs Konrad Rzeszutek Wilk
2014-04-11 18:08 ` [PATCH v3] Xen: Spread boot time page scrubbing across all available CPU's Konrad Rzeszutek Wilk
2014-04-11 18:38 ` Andrew Cooper
2014-04-11 19:19 ` Julien Grall
2014-04-12 13:19 ` Konrad Rzeszutek Wilk
2014-04-13 22:38 ` Tim Deegan
2014-04-14 9:39 ` Jan Beulich
2014-04-14 15:04 ` Konrad Rzeszutek Wilk [this message]
2014-04-14 15:18 ` NUMA nodes with no cpus Andrew Cooper
2014-04-14 15:38 ` [PATCH v3] Xen: Spread boot time page scrubbing across all available CPU's Jan Beulich
2014-04-14 15:54 ` Konrad Rzeszutek Wilk
-- strict thread matches above, loose matches on Subject: below --
2014-04-12 10:41 Konrad Rzeszutek Wilk
2014-04-13 22:45 ` Tim Deegan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140414150402.GE23371@phenom.dumpdata.com \
--to=konrad.wilk@oracle.com \
--cc=JBeulich@suse.com \
--cc=andrew.cooper3@citrix.com \
--cc=dario.faggioli@citrix.com \
--cc=keir@xen.org \
--cc=konrad@kernel.org \
--cc=malcolm.crossley@citrix.com \
--cc=tim@xen.org \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.