<?xml version="1.0"?>
<!-- name="generator" content="blosxom/2.0" -->
<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://my.netscape.com/publish/formats/rss-0.91.dtd">

<rss version="0.91">
  <channel>
    <title>Rusty's Bleeding Edge Page   </title>
    <link>http://ozlabs.org/~rusty/index.cgi</link>
    <description>Rusty's Bleeding Edge Page</description>
    <language>en</language>

<item>
    <title>libcwiid support for Guitar Hero World Tour Drums</title>
    <pubDate>Wed, 06 May 2009 19:12:00 GMT</pubDate>
    <link>http://ozlabs.org/~rusty/index.cgi/2009/05/06#2009-05-06</link>
    <description>
&lt;p&gt;
I use &lt;a href=&quot;http://abstrakraft.org/cwiid/&quot;&gt;libcwiid&lt;/a&gt; for my various
hacks, and recently I wanted to connect to the GH4 drumkit (which has been
documented thoroughly on &lt;a href=&quot;http://wiibrew.org/wiki/Wiimote/Extension_Controllers&quot;&gt;wiibrew.org&lt;/a&gt; but I couldn't find any patches.  After realizing
that the libcwiid project is pretty much abandonware, I imported the SVN
into mercurial and hacked in drum support.
&lt;/p&gt;

&lt;p&gt;
The start was the patch for GH guitar identification (found &lt;a href=&quot;http://abstrakraft.org/cwiid/ticket/79&quot;&gt;here&lt;/a&gt; but it didn't properly implement the new
detection scheme.  So I cleaned that up first.
&lt;/p&gt;

&lt;p&gt;
The code in general needs some love, and adding support for new devices breaks the ABI and API as it stands, yet that's fairly easy to fix.  But I don't really want to adopt YA puppy right now...
&lt;/p&gt;

&lt;p&gt;
So &lt;a href=&quot;http://ozlabs.org/~rusty/libcwiid-GHWT-drums.patch&quot;&gt;this patch&lt;/a&gt; should get you going on the drums!  Send me mail if you want support for other devices (the GHWT guitar should be easy), or other patches.  If there's enough interest I'll export the repository somewhere.
&lt;/p&gt;</description>
</item>
<item>
    <title>Gratuitous Arabella Pics</title>
    <pubDate>Tue, 14 Apr 2009 23:00:00 GMT</pubDate>
    <link>http://ozlabs.org/~rusty/index.cgi/2009/04/14#2009-04-14</link>
    <description>
&lt;p&gt; People do ask me how my daughter Arabella is going; she seems to
be thriving on 4-5 days every fortnight with me.  We go to the Central
Markets to shop.  We go swimming.  We lay on the grass in the
parklands over the road and read The Hobbit.  We nap (alot).
&lt;/p&gt;

&lt;p&gt; She's a mostly-happy wonderful baby, and even my favorite
photographs don't do her justice: &lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;
&lt;td&gt; Arabella December 2008&lt;br&gt;
(Professional photographer)
&lt;/td&gt;
&lt;td&gt; Arabella March 2009&lt;br&gt;
(My sister)
&lt;/td&gt;
&lt;td&gt; Arabella April 2009&lt;br&gt;
(&lt;a href=&quot;http://www.linkedin.com/in/avimiller&quot;&gt;Avi Miller&lt;/a&gt;)
&lt;/td&gt;
&lt;/tr&gt;
&lt;td&gt;&lt;img src=&quot;http://ozlabs.org/~rusty/Arabella/Arabella-sticking-tongue-out-12-2008.jpg&quot;&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src=&quot;http://ozlabs.org/~rusty/Arabella/Arabella-swimming-03-2009.jpg&quot;&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src=&quot;http://ozlabs.org/~rusty/Arabella/Arabella-gorgeous-4-2009.jpg&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;</description>
</item>
<item>
    <title>IBM LTC Tuz</title>
    <pubDate>Tue, 07 Apr 2009 17:16:00 GMT</pubDate>
    <link>http://ozlabs.org/~rusty/index.cgi/2009/04/07#2009-04-07</link>
    <description>
&lt;table border=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;
In response to the &lt;a href=&quot;http://lca2009.linux.org.au/&quot;&gt;LCA 2009&lt;/a&gt;
Dinner Auction which raised about &lt;a href=&quot;http://www.linux-magazine.com/online/news/helping_devils_at_linux_conf_au&quot;&gt;A$40k&lt;/a&gt;
to help &lt;a href=&quot;http://tassiedevil.com.au/&quot;&gt;save the Tasmanian Devil&lt;/a&gt;,
Linus agreed to &lt;a href=&quot;http://www.itwire.com/content/view/23976/1141&quot;&gt;
change the logo for the 2.6.29 release&lt;/a&gt; (making that patch was fun:
who knew there was a &lt;a href=&quot;http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=scripts/pnmtologo.c&quot;&gt;PNM reader&lt;/a&gt; in the kernel source?)
&lt;/p&gt;

&lt;p&gt; No surprise that Tuz has also been seen moonlighting around the
IBM Linux Technology Center:&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;img src=&quot;http://ozlabs.org/~rusty/ibm-tuz.png&quot;&gt;
&lt;/td&gt;
&lt;/table&gt;</description>
</item>
<item>
    <title>Valid Uses of Macros</title>
    <pubDate>Fri, 13 Mar 2009 15:57:00 GMT</pubDate>
    <link>http://ozlabs.org/~rusty/index.cgi/2009/03/13#2009-03-13</link>
    <description>
&lt;p&gt; So, C has a preprocessor, and it can be used for evil:
particularly function-style macros (#define func(arg)) are generally
considered suspect.  Old-timers used to insist all macros were
SHOUTED, but it can make innocent (but macro-heavy) code damn ugly.
&lt;/p&gt;

&lt;p&gt; Remember, it's only a problem when it's &lt;a
href=&quot;http://ozlabs.org/~rusty/index.cgi/tech/2008-03-18.html&quot;&gt;Easy to Misuse&lt;/a&gt;, and if you've written something
that's easy to misuse, maybe a rethink is better than an ALL CAPS warning.
&lt;/p&gt;

&lt;p&gt;
There is one genuine and unescapable use for macros:
&lt;dl&gt;
&lt;dt&gt; &lt;strong&gt;Macros which deal with types, or take any type&lt;/strong&gt; &lt;/dt&gt;
&lt;dd&gt; The classic here is &lt;pre&gt;#define new(type) ((type *)malloc(sizeof(type)))&lt;/pre&gt;But consider also the Linux kernel's min() implementation:
&lt;pre&gt; #define min(x,y) ({ \
	typeof(x) _x = (x);	\
	typeof(y) _y = (y);	\
	(void) (&amp;_x == &amp;_y);		\
	_x &lt; _y ? _x : _y; })
&lt;/pre&gt; which uses two GCC extensions to produce a warning if x and y are not
exactly the same type.
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/p&gt;

&lt;p&gt;
And there are several justifiable but more arguable cases:
&lt;dl&gt;
&lt;dt&gt; &lt;strong&gt;Const-correct wrappers&lt;/strong&gt; &lt;/dt&gt;
&lt;dd&gt; If you need to wrap a struct member access, it's annoying to do
      it as an inline function.  To be general a function needs to
      take a const pointer argument, then cast away the const (see
      strchr).  Const exists for a reason, and stealing it from your callers
      is a bad idea.  A macro
&lt;pre&gt;#define tsk_foo(tsk) ((tsk)-&gt;foo)&lt;/pre&gt; maintains const correctness, at
	the slight cost of type safety (you could hand anything with a
	foo member there, though it's unlikely to cause problems and
	can be fixed with a more complex macro.
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Debugging macros&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt; Generally just add __FILE__ and __LINE__ to a function call.  The
     non-debug versions are generally real functions.
&lt;/dd&gt;

&lt;dt&gt; &lt;strong&gt;Genuinely fancy tricks&lt;/strong&gt; &lt;/dt&gt;
&lt;dd&gt; There's no good way around a macro for things like ARRAY_SIZE and BUILD_BUG_ON (these taken from CCAN):
&lt;pre&gt;
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + _array_size_chk(arr))
#define BUILD_ASSERT(cond) do { (void) sizeof(char [1 - 2*!(cond)]); } while(0)
&lt;/pre&gt;
&lt;/dl&gt;

&lt;p&gt;
More questionable still:
&lt;dl&gt;
&lt;dt&gt; &lt;strong&gt;Macros which declare things&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt;  This is for things which need initialization, eg. LIST_HEAD
      in the kernel (or ccan/list) expects an &quot;empty&quot; list to be pointing
      to itself.  While this is convenient, nothing else in C
      self-initializes so it's arguably better to provide an
      &quot;EMPTY_LIST(name)&quot; macro.  You get a nice crash if you forget
      (except on stack vars). &lt;/dd&gt;
&lt;br&gt;

&lt;dt&gt; &lt;strong&gt;Macros which iterate&lt;/strong&gt;&lt;/dt&gt;

&lt;dd&gt; list_for_each() (ccan/list.h version of the kernel's list_for_each_entry):
&lt;pre&gt;
#define list_for_each(h, i, member)					\
	for (i = container_of_var(debug_list(h)-&gt;n.next, i, member);	\
	     &amp;i-&gt;member != &amp;(h)-&gt;n;					\
	     i = container_of_var(i-&gt;member.next, i, member))
&lt;/pre&gt;
It's less explicit, but much shorter than having three macros and using
them to loop:
&lt;pre&gt;
for (i = list_start(&amp;list, member); i != list_end(&amp;list, member); i = list_next(&amp;list, member, i))
&lt;/pre&gt;

If we sacrifice a little efficiency for convenience, we can make list_start()
and list_next() evaluate to NULL at the end of the list, and I prefer it over
the list_for_each() macro:
&lt;pre&gt; for (i = list_start(&amp;list, member); i; i = list_next(&amp;list, member, i))
&lt;/pre&gt;
&lt;/dd&gt;
&lt;/dl&gt;

Of course, it wouldn't be a complete post on macros without mentioning
things you should never do:

&lt;dl&gt;
&lt;dt&gt; &lt;strong&gt;Modify your arguments.&lt;/strong&gt;
&lt;dd&gt; C coders don't expect magic changes to parameters.  From kernel.h:     
&lt;pre&gt;#define swap(a, b) \
	do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
&lt;/pre&gt;
&lt;/dd&gt;

&lt;dt&gt; &lt;strong&gt;Embed control statements to places outside the macro.&lt;/strong&gt;
&lt;dd&gt; Putting 'return' in macros is only ok if the macro is called, say,
  COMPLAIN_AND_RETURN.  And then it's probably still a bad idea. &lt;/dd&gt;
&lt;br&gt;

&lt;dt&gt; The classics: use too few brackets, or allow multi-evaluation. &lt;/dt&gt;
&lt;dd&gt; The former is unforgivable; it cost be 1/2 a day of my life once
     when I was younger and using another coder's RAD2DEG() macro.
     The latter can be avoided with gcc extensions (see min() above), or
     sometimes using sizeof().&lt;/dd&gt;
&lt;/dl&gt;</description>
</item>
<item>
    <title>linux.conf.au 2009</title>
    <pubDate>Mon, 26 Jan 2009 22:00:00 GMT</pubDate>
    <link>http://ozlabs.org/~rusty/index.cgi/2009/01/26#2009-01-26</link>
    <description>
&lt;p&gt;
This is a braindump so I remember, not any kind of ordered report.
&lt;/p&gt;

&lt;p&gt; Newcomer's session worked well: it's not about the content so much
as making people feel welcome and less lost.  (It's also about them
meeting each other, which is my excuse for a deliberately lacklustre
presentation).  I said &quot;newbie&quot; twice though, and I hate that word.
And I am just not sure what to say to someone &lt;a
href=&quot;http://www.noogz.net/website/blog/life/20090119-Day0.html&quot;&gt;who
says last year's was better&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt; Miniconfs are supposed to be more chaotic than the main conf, so
that's my excuse for lacklustre presentation for the Kernel miniconf.
It was basically a bullet list of what's been happening with cpumask
et al.  Linus was off scuba diving somewhere, but noone shouted me
down as an idiot, so count it as a win.  Paul McKenney's talk was good
as always, but too long for the slot (he had to skip slides just as he
was getting to the stuff I hadn't heard before).  &lt;/p&gt;

&lt;p&gt; Attended the Geek Parenting session at LinuxChix miniconf; my
take-home point was about finding ways of encouraging strengths (kids
hitting each other with sticks?  How about fencing lessons?) but not
giving up on activities where kids need to get over a hump (example
was violin IIRC).  (Other take-home point: I should ask Karen and
Bdale for advice, since Edale turned out to so well...)  &lt;/p&gt;

&lt;p&gt; Monday evening spent worrying at my Free as In Freedom talk.  One
reason I was really hoping that Kim Weatherall would make it to Hobart
was that it needed some tightening.  However, when unhappy with the
refinement of the content, you can always make up for it by doing
something flashy and stupid.
&lt;/p&gt;

&lt;p&gt; Tuesday I was less coherent in my choices of what I attended
(Monday was mainly kernel miniconf).  My talk at the Free As In
Freedom talk was lukewarm, but I ended with the definitely
unrepeatable &quot;Software Patents as Interpretive Dance&quot;.  And I
doubt the camera captured it.  &lt;/p&gt;

&lt;p&gt; Wednesday's keynote by Tom Limoncelli was good, but mis-aimed for
most of the audience who are not sysadmins.  He would probably have
re-calibrated it if it had been later in the week and he'd had more
exposure to us.  Jeremy Kerr's spufs talk was solid, and he rightly
spent more time on the userspace SPU programming interface than on the
filesystem as a fileystem.  Peter Hutterer's &quot;Your input is important
to us!&quot; was a classic &quot;here's where the cruft is and here's what we're
doing about it&quot; talk.  Then came my Lguest Tutorial prep session and
Part I.  &lt;/p&gt;

&lt;p&gt; After last year where almost noone sailed smoothly through the
preparation, I spent much more time on preparing the images and kernel
for everyone.  That way you could either boot my kernel on your laptop
(and live without some things working for the duration), or use kvm or
even qemu to run my entire image.
&lt;/p&gt;

&lt;p&gt; Unfortunately I blew away two required files in a last-minute
cleanup of the kernel tree (I pre-built it to save compile time, but
it always links vmlinux so I deleted those files to save space).
Getting those back inside the image was an exercise in pain, as I
bzip2'd the image on the USB keys otherwise I could have mounted them
in place and fixed it myself.
&lt;/p&gt;

&lt;p&gt; So instead of scaring people off my tutorial with my sheer
competence, I scared them off with incompetence.  Colour me deeply,
deeply annoyed.
&lt;/p&gt;

&lt;p&gt; Wednesday was the Penguin Dinner; traditionally it'd be Friday
night, but it was Wed in Melbourne because of the night market and
that seems to have stuck.  I used to say that I disliked the auction;
it goes on too long and very quickly 99% of people can't bid any more.
And let's be honest: I'm just not that interesting that you want to
listen to me for half the evening.  But the emergence of consortia in
recent years has changed this: it's not really an auction at all any
more but a chance to get people to pledge Random Cool Things.  Proof:
the final consortium bid against itself several times.  And we're
actually big enough to make a difference to a useful cause.  We still
need half-time entertainment or something...&lt;/p&gt;

&lt;p&gt; Thursday was Angela Beesley's keynote: again I felt that her
content could have been more focussed for this crowd (assume everyone
knows the basics and talk more about interesting facts and details).
Also she was nervous and followed her script at expense of showing
passion (until questions).
&lt;/p&gt;

&lt;p&gt; My tutorial went well I think: more finely calibrated this year,
in that everyone completed something, and at least two people
completed the Advanced series of problems.  I will have to add some
more advanced tasks for 2010 (yes, I have to do it again: I'm still
pissed off at my setup blunder).  A few people repeated it from last
year; is that good or bad?
&lt;/p&gt;

&lt;p&gt; I went to Jeff Arnold's ksplice talk; I like ksplice but I had
some lingering questions.  I ended by promising to review the code for
him.  I want this in my kernel, even if my distribution doesn't: we've
done wackier things for less benefit.
&lt;/p&gt;

&lt;p&gt; I hit the end of Hugh's talk: seemed like quite a good &quot;grab bag
of tools and techniques&quot; talk.  As expected (having worked with Hugh
of course) I had heard of most of them, but not all.  One I will
review on video where I can google while listening.
&lt;/p&gt;

&lt;p&gt; Friday came, and my first day with no presentation!  Simon Phipps
gave an excellent keynote.  He showed himself to be part of our world
and gave a nice high-level &quot;here's how I (and to some extent, Sun) see
things&quot; without wandering into a product launch or equivalent.  I know
Richard Keech saw differently, but I don't think he misrepresented
RedHat (at least, assuming the audience were clued up: I can see how a
more general audience could have gained a distorted impression).
&lt;/p&gt;

&lt;p&gt; Kimberlee Cox's HyKim robotic bear talk was saved by the cool
content, but she's not a strong speaker and several audience questions
made her seem out of her depth on the details (I didn't understand
their points either, so I can't be sure on this one).  But I do know
that sometimes speakers switch modes from general into specific when
asked a detailed question and you get an insight into how much they've
been holding back so as not to confuse/bore/intimidate you.  I didn't
get that here.
&lt;/p&gt;

&lt;p&gt; I skipped most of Bdale's &quot;Free As In Beard&quot; lunctime session (not
my pun, but couldn't resist), but suffice to say I will neither be
waxing my chest nor singing Queen songs next year.  Honestly, noone
wants that.
&lt;/p&gt;

&lt;p&gt; I was late to Adam Jackson's Shatter talk and then late to Rob
Bradford's Clutter talk, so I wasted my time in both of them.  My own
fault, yet it annoys me every year when it happens.
&lt;/p&gt;

&lt;p&gt; In the morning I had volunteered to take care of the Lightning
Talks, and then went and found &lt;a href=&quot;http://bethesignal.org/&quot;&gt;Jeff
Waugh&lt;/a&gt; to &lt;em&gt;actually&lt;/em&gt; take care of them.  He acked, and I
didn't have to think about it again; of course, he did an awesome job.
My contribution was to start (noone wants slot #1 it seems), and give
a very quick and dirty plug for ccan and libantithread.  &lt;/p&gt;

&lt;p&gt; The Google Party, like the PDNS and Speaker's Dinner, was well
done.  Conrad Parker asked if anyone else had been to all 10
conferences; as far as I know, only he, Andrew Tridgell, Hugh Blemings
and I have been to all of them since CALU.  We should form some kind
of Secret Society.  And only Tridge has presented at every single one.
&lt;/p&gt;

&lt;p&gt; I also discussed with Dave Mandala an awesome project which would
also make a great 2010 presentation if it comes together.  6am flight
home on Saturday morning, and I am now mostly recovered.
&lt;/p&gt;</description>
</item>
<item>
    <title>libantithread 0.1</title>
    <pubDate>Wed, 14 Jan 2009 11:48:00 GMT</pubDate>
    <link>http://ozlabs.org/~rusty/index.cgi/2009/01/14#2009-01-14</link>
    <description>
&lt;p&gt;Finally, an antithread release!&lt;/p&gt;

&lt;center&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src=&quot;http://ozlabs.org/~rusty/arabella-antithread-frame-00000000.jpg&quot;&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src=&quot;http://ozlabs.org/~rusty/arabella-antithread-frame-00000102.jpg&quot;&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src=&quot;http://ozlabs.org/~rusty/arabella-antithread-frame-00000517.jpg&quot;&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src=&quot;http://ozlabs.org/~rusty/arabella-antithread-frame-00001021.jpg&quot;&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src=&quot;http://ozlabs.org/~rusty/arabella-antithread-frame-00003649.jpg&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/center&gt;

&lt;p&gt;
(You can also download an &lt;a href=&quot;http://ozlabs.org/~rusty/arabella-antithread-movie.ogv&quot;&gt;Ogg Theora Video&lt;/a&gt; of each 1% improved frame).
&lt;/p&gt;

&lt;p&gt;Sometimes we use threads simply because using processes and shared
memory is harder.  But threads share far too much; libantithread is my
solution.&lt;/p&gt;

&lt;p&gt;Its in &lt;a href=&quot;http://ccan.ozlabs.org&quot;&gt;CCAN&lt;/a&gt;, and it's at the
&quot;useful demonstration&quot; stage.  It badly needs a nice load of
documentation, but there are two example programs:
&lt;ul&gt;
&lt;li&gt; A simple async DNS lookup engine.  We fire off argc-1 antithreads
     to do the lookups.
&lt;li&gt; A more complex generic algorithm example, illustrated above.  Random
     blended triangles try to match a given image.
&lt;/ul&gt;

&lt;p&gt;Simplest is to &lt;a href=&quot;http://ccan.ozlabs.org/ccan.tar.bz2&quot;&gt;download the
CCAN tarball of everything&lt;/a&gt;, do a &quot;make&quot; and then go into ccan/ccan/antithread/examples and &quot;make&quot; there.&lt;/p&gt;</description>
</item>
<item>
    <title>Fun with cpumasks</title>
    <pubDate>Wed, 07 Jan 2009 12:01:00 GMT</pubDate>
    <link>http://ozlabs.org/~rusty/index.cgi/2009/01/07#2009-01-07</link>
    <description>
&lt;p&gt;
I've been meaning for a while to write up what's happening with
cpumasks in the kernel.  Several people have asked, and it's not
obvious so it's worth explaining in detail.  Thanks to Oleg Nesterov
for the latest reminder.
&lt;/p&gt;

&lt;h4&gt; The Problems &lt;/h4&gt;
&lt;p&gt;
The two obvious problems are
&lt;ol&gt;&lt;li&gt; Putting cpumasks on the stack limits us to NR_CPUS around 128, and
&lt;li&gt; The whack-a-mole attempts to fix the worst offenders is a losing game.
&lt;/ol&gt;
&lt;/p&gt;

&lt;p&gt; For better or worse, people want NR_CPUS 4096 in stock kernels
today, and that number is only going to go up.  &lt;/p&gt;

&lt;p&gt;
Unfortunately, our merge-surge development model makes whack-a-mole
the obvious thing to do, but the results (creeping in largely
unnoticed) have been between awkward and horrible.  Here's some
samples across that spectrum:

&lt;ol&gt;
&lt;li&gt; cpumask_t instead of struct cpumask.  I gather that this is a relic
     from when cpus were represented by an unsigned long, even though
     now it's always a struct.

&lt;li&gt; cpu_set/cpu_clear etc. are magic non-C creatures which modify
     their arguments through macro magic:
&lt;pre&gt;
#define cpu_set(cpu, dst) __cpu_set((cpu), &amp;(dst))
&lt;/pre&gt;

&lt;li&gt; cpumask_of_cpu(cpu) looked like this:
&lt;pre&gt;
#define cpumask_of_cpu(cpu)
(*({
        typeof(_unused_cpumask_arg_) m;
        if (sizeof(m) == sizeof(unsigned long)) {
                m.bits[0] = 1UL&lt;&lt;(cpu);
        } else {
                cpus_clear(m);
                cpu_set((cpu), m);
        }
        &amp;m;
}))
&lt;/pre&gt;

Ignoring that this code has a silly optimization and could be better
written, it's illegal since we hand the address of a
going-out-of-scope local var.  This is the code which got me looking
at this mess to start with.

&lt;li&gt; New &quot;_nr&quot; iterators and operators have been introducted to only
go to up to nr_cpu_ids bits instead of all the way to NR_CPUS, and
used where it seems necessary.  (nr_cpu_ids is the actual cap of
possible cpu numbers, calculated at boot).

&lt;li&gt; Several macros contain implicit declarations in them,  eg:
&lt;pre&gt;
#define CPUMASK_ALLOC(m)        struct m _m, *m = &amp;_m
...
#define node_to_cpumask_ptr(v, node)                                    \
                cpumask_t _##v = node_to_cpumask(node);                 \
                const cpumask_t *v = &amp;_##v

#define node_to_cpumask_ptr_next(v, node)                               \
                          _##v = node_to_cpumask(node)
&lt;/pre&gt;
&lt;/ol&gt; 
&lt;/p&gt;

&lt;p&gt;
But eternal vigilance is required to ensure that someone doesn't add
another cpumask to the stack, somewhere.  This isn't going to happen.
&lt;/p&gt;

&lt;h4&gt; The Goals &lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;No measurable overhead for small CONFIG_NR_CPUS.
&lt;li&gt;As little time and memory overhead for large CONFIG_NR_CPUS kernels booted
    on machined with small nr_cpu_ids.
&lt;li&gt;APIs and conventions that reasonable hackers can follow who don't care
    about giant machines, without screwing up those machines.
&lt;/ul&gt;

&lt;h4&gt; The Solution &lt;/h4&gt;

&lt;p&gt;
These days we avoid Big Bang changes where possible.  So we need to
introduce a parallel cpumask API and convert everything across, then
get rid of the old one.
&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt; The first step is to introduce replacemenst for the cpus_*
     functions.  The new ones start with cpumask_; making names longer
     is always a little painful, but it's now consistent.  The few
     operators which started with cpumask_ already were converted in
     one swoop (they were rarely used).  These new functions take
     (const) struct cpumask pointers, and may only operate on some
     number of bits (CONFIG_NR_CPUS if it's small, otherwise
     nr_cpu_ids).  This replacement is fairly simple, but you have to
     watch for cases like this:

&lt;pre&gt;
	for_each_cpu_mask(i, my_cpumask)
		...
	if (i == NR_CPUS)
&lt;/pre&gt;

That final test should be &quot;(i &gt;= nr_cpu_ids)&quot; to be safe now:
&lt;pre&gt;
	for_each_cpu(i, &amp;my_cpumask)
		...
	if (i &gt;= nr_cpu_ids)
&lt;/pre&gt;
&lt;/li&gt;

&lt;li&gt; The next step is to deprecate cpumask_t and NR_CPUS
     (CONFIG_NR_CPUS is now defined even for !SMP).  These are minor
     annoyances but more importantly in a job this large and slow they
     mark where code needs to be inspected for conversion.  &lt;/li&gt;

&lt;li&gt; cpumask_var_t is introduced to replace cpumask_t definitions
    (except in function parameters and returns, that's always (const)
    struct cpumask *).  This is just struct cpumask[1] for most
    people, and alloc_cpumask_var/free_cpumask_var do nothing.
    Otherwise, it's a pointer to a cpumask when
    CONFIG_CPUMASK_OFFSTACK=y.&lt;/li&gt;

&lt;li&gt; alloc_cpumask_var currently allocates all CONFIG_NR_CPUS bits, and
    zeros any bits between nr_cpu_ids and NR_CPUS.  This is because
    there are still some uses of the old cpu operators which could
    otherwise foul things up.  It will be changed to do the minimal
    allocation as the transfer progresses.&lt;/li&gt;

&lt;li&gt; New functions are added to avoid common needs for temporary
     cpumasks.  The two most useful are for_each_cpu_and() (to iterate
     over the intersection of two cpumasks) and cpu_any_but() (to
     exclude one cpu from consideration). &lt;/li&gt;

&lt;li&gt; Another new function added for similar reasons was work_on_cpu().
     There was a growing idiom of temporarily setting the current
     thread's cpus_allowed to execute on a specific CPU.  This not
     only requires a temporary cpumask, it is potentiall buggy since
     it races with userspace setting the cpumask on that thread.

&lt;li&gt; to_cpumask() is provided to convert raw bitmaps to struct cpumask
    *.  In some few cases, cpumask_var_t cannot serve because we can't
    allocate early enough or there's no good place (or I was too
    scared to try), and I wanted to get rid of all 'struct cpumask'
    declarations as we'll see in a moment.&lt;/li&gt;

&lt;li&gt; Architectures which have no intention of setting
    CONFIG_CPUMASK_OFFSTACK need do very little.  We should convert
    them eventually, but there's no real benefit other than cleanup
    and consistency.&lt;/li&gt;

&lt;li&gt; I took the opportunity to centralize the cpu_online_map etc
    definitions, because we're obsoleting them anyway.  &lt;/li&gt;

&lt;li&gt; cpu_online_mask/cpu_possible_mask etc (the pointer versions of the
    cpu_online_map/cpu_possible_map they replace) are const.  This
    means that the few cases where we really want to manipulate them,
    the new set_cpu_online()/set_cpu_possible() or
    init_cpu_online()/init_cpu_possible() should be used.  &lt;/li&gt;

&lt;li&gt; We will change 'struct cpumask' to be undefined for
    CONFIG_CPUMASK_OFFSTACK=y.  This can only be done once all
    cpumask_t (ie. struct cpumask) declarations are removed, including
    globals and from structures.  Most of these are a good idea
    anyway, but some are gratuitous.  But this will instantly catch
    any attempt to use struct cpumask on the stack, or to copy it (the
    latter is dangerous since cpumask_var_t will not allocate the
    entire mask). &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt; Conclusion &lt;/h4&gt;
&lt;p&gt;
At this point, we will have code that doesn't suck, rules which can be
enforced by the compiler, and the possibility of setting
CONFIG_NR_CPUS to 16384 as the SGI guys really want.
&lt;/p&gt;

&lt;p&gt; Importantly, we are forced to audit all kinds of code.  As always,
some few were buggy, but more were unnecessarily ugly.  With less
review happening these days before code goes in, it's important that
we strive to leave code we touch neater than when we found it. &lt;/p&gt;</description>
</item>
  </channel>
</rss>