9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: Linus Torvalds <torvalds@osdl.org>
To: Rob Pike <rob@mightycheese.com>
Cc: 9fans@cse.psu.edu
Subject: Re: [9fans] Re: Threads: Sewing badges of honor onto a Kernel
Date: Fri, 27 Feb 2004 08:57:46 -0800	[thread overview]
Message-ID: <Pine.LNX.4.58.0402270814250.2563@ppc970.osdl.org> (raw)
In-Reply-To: <98DCC07A-6939-11D8-B851-000A95B984D8@mightycheese.com>



On Fri, 27 Feb 2004, Rob Pike wrote:
>
>  > Having a pointer that sometimes works, and sometimes doesn't, based  on who
>  > uses it - that's just crazy talk.
>
> put in those terms, it sounds weird, but it's not.  consider the old u.
> area in unix. that was a piece of address space with the same virtual
> address in all processes but a different content.

I hate to put it to you, Rob, but that sucks. It sucks so hard that it's
not even funny.

Playing tricks with the VM is a cool hack, and we've considered it
multiple times, but in the end sanity has always prevailed. Playing VM
tricks is _expensive_. It looks cheap because the access code "just
works", but the expense is in

 - wasting TLB entries (all sane CPU's have big "fixed" areas that are
   better on the TLB for system mode - large pages, BAT registers, or just
   architected 1:1 mappings). The kernel should use them, because the
   fewer TLB entries the kernel uses, the more there are for user space to
   waste. But that implies that the kernel shouldn't play any VM tricks
   with its own data - the VM is for user space (yeah, the kernel ends up
   wanting to use the VM hardware for some things, but it's discouraged)

 - CPU's with hardware TLB lookup have to have separate page tables for
   different CPU's. Which means not only that you're wasting memory on
   having <n> copies of the thing, it also means that now you have to have
   code to maintain coherency between those separate page tables, and have
   to have locking.

   Having just one copy is just better. Two copies of the same thing is
   bad.

 - TLB invalidates are just a lot more expensive than changing a register
   around. It's bad even on "good" hardware, it's totally unacceptable on
   anything with a virtual cache, for example.

So the kernel internally has always had the stack pointer register as the
main "thread pointer". It did that even before SMP, just because it was
simpler and faster. With SMP, doing anything else becomes unacceptable.

>  the system used the fact that the addresses aliased that way.  plan 9's
> thread model does a similar thing by constructing a special storage
> class for data private to each process.  for instance, one can have a
> variable with the same address in each process, call it tp, that points
> to the thread-specific data, so you can write code like
>
> 	printf("my id is %d\n", tp->id);

Yes. And you pay the price. For no good reason, I may add, since you
traditionally have been able to do the same by just having to add some
explicit thread tracking (it wouldn't be "tp->id", it would be
"mythread()->tp->id") or by adding compiler support to make the syntax be
easier.

These days, if you want to avoid the syntax of carrying that per-thread
pointer around, we have compiler support, ie you can do

	__thread struct mystruct *tp = NULL;

and now "tp" is a per-thread variable. Behind the schenes the compiler
will change it to be an offset off the TLS pointer, pretty much exactly
the same way it does position-independent code.

>  > The same way it creates any other storage: with mmap() and brk(). You just
>  > malloc the thing, and you pass in the new stack as an argument to the
>  > thread creation mechanism (which linux calls "clone()", just to be
>  > different).
>
> that wasn't what i was asking.  i was referring to this special storage
> class. how does a thread identify who it is?

A long time ago, it was literally a "gettid()" system call. If you wanted
the thread-local space, you followed that by a index lookup.

It's not insanely expensive if you avoid re-generating the thread-local
pointer all the time, and pass it down as a regular argument, but it is
obviously syntactically not pretty.

These days - mostly thanks to compiler and library advances, not so much
any real kernel changes - the thread infrastructure sets up its local
pointers in registers, so that you can use the above "__thread"
specifier in the compiler, and when you access

	tp->id

the compiler will actually generate

	movl    %gs:tp@NTPOFF, %eax
	movl    (%eax), %eax

for you (on other platforms that have compiler support of thread-local
storage it usually would end up being a indirect access through a regular
register).

The linker fixes these things up, the same way it does things like GOT
tables etc.

> ah, i see in later mail that you answered this. there are now pointers
> created in the user space (i think) to thread-local storage.  how is it
> accessed, that is, how does the user process derive the pointer to it?
> this state stuff did not exist when we did the inferno port.

See above. If you control your environment (ie you don't have to worry
about having arbitrary TLS space), you can do better with the stack
register trick the kernel uses, but indirection will handle the general
case.

> it will work; it's the magic address bits hack.  which kernel version
> introduced this stuff?  i've heard people say that 2.6 is the first one
> with the default thread model being 'efficient' and 'good', but i don't
> know the specifics.  i've also heard that they can be retrofitted to
> 2.4.

The new threading model in 2.6.x is really more about signal handling than
anything else. The _real_ problem with the original clone() implementation
had nothing to do with the VM, and had everything to do with insane POSIX
shared signal semantics. It's really hard to get the POSIX thread signal
semantics rigt, since the whole pthreads thing really was designed for
having all threads run within one master process, and Linux never had the
notion of "process vs threads".

The signal case that is hard to get right in POSIX is the fact that signal
masks are thread-local, yet their effect is "process global" (ie when you
change the signal mask of your thread, that means that you suddenly now
potentially start accepting pending signals that were shared process
global). I still don't like that POSIX model, and I didn't see any sane
way to do it efficiently with truly independent threads that don't have
the notion of a "process" that encompasses them.

What 2.6.x (and the 2.4.x back-port) does is to just accept the fact that
there is a "thread group leader" (that's what the CLONE_THREAD flag does:
if it is set, you share the thread group leader, if it is clear you create
a new thread group), and that pending signal state really is shared in the
thread group.

The VM side has always been the same: if you share the VM, you share
everything. There literally isn't any thread-local storage from a VM
standpoint, there are only thread-local registers that point to different
areas of memory.

> it's interesting you advocate using registers for the magic storage
> class. it's a great trick when you can do it - plan 9 uses it in the
> kernel on machines with lots of registers - but it's not so great on a
> machine with too few registers, like the x86.

Well, even in the absense of a register, you can always just have a system
call to ask what the pointer should be. That really does work very well,
as long as your programming model is about explicit thread pointers (which
pthreads is) so that you don't have to do it all the time.

And the x86 really is the worst possible case, in this situation, because
it is so register-starved anyway. But happily, it has some (very ugly)
legacy registers that have to be user-visible, and have to be saved and
restored anyway, and that nobody sane really wants to use, so the thread
model can use them.

Making the threaded stuff explicit helps avoid confusion. Now, if somebody
takes an address of a per-thread variable, it is clear that that address
is the address of the variable IN THAT THREAD. You can pass it along, but
when you pass it along to another thread, it doesn't change value - it
still points to the exact same thread-local variable in the _original_
thread.

(Obviously you can pass around offsets to the thread-local space if you
want to, although I can't really see why you'd do it).

And I hope it's clear by now that because the thing is entirely in
registers, that "thread model" is pretty much all in user space. It needs
no kernel support, although some of the interfaces are obviously done
certain ways to make it easier to do (ie the kernel does know about a TLS
pointer at thread setup, even if the kernel doesn't actually _use_ it for
anything, it just sets up the register state as indicated by the parent of
the thread).

			Linus


  reply	other threads:[~2004-02-27 16:57 UTC|newest]

Thread overview: 203+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-02-27  4:45 [9fans] " dbailey27
2004-02-27  5:05 ` Scott Schwartz
2004-02-27  5:06 ` andrey mirtchovski
2004-02-27  5:05   ` dbailey27
2004-02-27  5:26     ` Rob Pike
2004-02-27  5:37       ` dbailey27
2004-02-27  5:47         ` ron minnich
2004-02-27  7:43           ` boyd, rounin
2004-02-27  5:54         ` Rob Pike
2004-02-27  6:01           ` dbailey27
2004-02-29 21:14             ` boyd, rounin
2004-03-01  4:40               ` Kenji Okamoto
2004-02-27  5:06   ` dbailey27
2004-02-27  5:28 ` Rob Pike
2004-02-27  6:19   ` Scott Schwartz
2004-02-28  9:38   ` Bruce Ellis
2004-02-28 10:10     ` Charles Forsyth
2004-02-28 10:28       ` Bruce Ellis
2004-02-28 10:11     ` [9fans] limbo? David Tolpin
2004-02-28 10:22       ` Geoff Collyer
2004-02-28 19:27       ` Charles Forsyth
2004-02-28 21:16       ` Russ Cox
2004-02-28 13:28     ` [9fans] Threads: Sewing badges of honor onto a Kernel boyd, rounin
2004-02-29 20:59     ` boyd, rounin
2004-02-27  5:43 ` ron minnich
2004-02-27  5:50   ` George Michaelson
2004-02-27  5:59     ` ron minnich
2004-02-27  6:07       ` George Michaelson
2004-02-27  7:47       ` boyd, rounin
2004-02-27  6:20 ` [9fans] " Linus Torvalds
2004-02-27  6:31   ` dbailey27
2004-02-27  6:49     ` Linus Torvalds
2004-02-27  6:48       ` dbailey27
2004-02-27  7:04         ` Linus Torvalds
2004-02-27  7:06           ` dbailey27
2004-02-27  7:30             ` a
2004-02-27  7:49               ` dbailey27
2004-02-27  7:39             ` Lucio De Re
2004-02-27  7:57               ` Linus Torvalds
2004-02-27  8:00                 ` Rob Pike
2004-02-27  8:05                 ` Lucio De Re
2004-02-27  8:06                 ` boyd, rounin
2004-02-27  7:47             ` Linus Torvalds
2004-02-27  7:46               ` dbailey27
2004-02-27  8:08                 ` Linus Torvalds
2004-02-27  8:04                   ` dbailey27
2004-02-27  8:19                     ` Geoff Collyer
2004-02-27 15:28                       ` Rob Pike
2004-02-27 16:57                         ` Linus Torvalds [this message]
2004-02-27  8:11                   ` Lucio De Re
2004-02-27  8:17                     ` Rob Pike
2004-02-27  8:31                       ` Lucio De Re
2004-02-27  9:46                         ` Linus Torvalds
2004-02-27  8:44                           ` boyd, rounin
2004-02-27 10:00                             ` Linus Torvalds
2004-02-27  9:52                           ` Lucio De Re
2004-02-27 10:00                             ` Charles Forsyth
2004-02-27 10:07                               ` Lucio De Re
2004-02-27 10:14                                 ` Charles Forsyth
2004-02-27 10:24                                   ` Lucio De Re
2004-02-27 11:40                                     ` C H Forsyth
2004-02-28  9:58                               ` Bruce Ellis
2004-02-27 10:11                             ` Linus Torvalds
2004-02-27 10:13                               ` Lucio De Re
2004-02-27 10:36                                 ` Linus Torvalds
2004-02-27 19:07                   ` Donald Brownlee
2004-02-27  7:47               ` Fco.J.Ballesteros
2004-02-27  8:04               ` boyd, rounin
2004-02-29 21:17             ` boyd, rounin
2004-02-27  7:12           ` Rob Pike
2004-02-27  7:17             ` Charles Forsyth
2004-02-27  8:01               ` boyd, rounin
2004-02-27  8:06             ` Scott Schwartz
2004-02-27  8:15               ` Rob Pike
2004-02-27  7:06         ` Lucio De Re
2004-02-27  7:53         ` boyd, rounin
2004-02-27 12:23       ` Dave Lukes
2004-02-27 16:08         ` Linus Torvalds
2004-02-27 16:39           ` Dave Lukes
2004-02-27 17:05             ` Linus Torvalds
2004-02-27 17:03               ` Fco.J.Ballesteros
2004-02-27 17:50               ` Dave Lukes
2004-02-27 18:26                 ` Linus Torvalds
2004-02-27 18:27                   ` matt
2004-02-27 18:39                     ` andrey mirtchovski
2004-02-27 23:39                   ` boyd, rounin
2004-03-01  8:44                     ` Fco.J.Ballesteros
2004-03-01  8:48                       ` Fco.J.Ballesteros
2004-03-01  8:59                         ` Lucio De Re
2004-03-01  9:04                           ` Fco.J.Ballesteros
2004-03-01  9:16                             ` Kenji Okamoto
2004-03-01  9:19                               ` Kenji Okamoto
2004-03-01 15:47                           ` ron minnich
2004-03-01 16:23                             ` lucio
2004-03-01 18:04                               ` viro
2004-03-02  9:37                               ` Douglas A. Gwyn
2004-03-02 10:16                                 ` lucio
2004-03-03  1:36                             ` Kenji Okamoto
2004-03-02  1:40                       ` rob pike, esq.
2004-02-27 23:20               ` boyd, rounin
2004-03-01 10:34               ` Bengt Kleberg
2004-03-01 14:40                 ` Russ Cox
2004-03-01 15:17                   ` boyd
2004-03-02  9:42                   ` Bengt Kleberg
2004-03-02  9:53                     ` Fco.J.Ballesteros
2004-03-02 14:51                     ` ron minnich
2004-03-03  9:33                       ` Bengt Kleberg
2004-03-03 12:59                         ` ron minnich
2004-03-03 13:10                           ` Fco.J.Ballesteros
2004-03-03 13:21                             ` ron minnich
2004-03-04 10:00                               ` Yi Li
2004-03-04 11:22                                 ` Fco.J.Ballesteros
2004-03-05 15:17                                   ` Yi Li
2004-03-03 13:38                             ` rog
2004-03-03 17:57                             ` a
2004-03-01 15:56                 ` ron minnich
2004-03-02  9:42                   ` Bengt Kleberg
2004-02-27 17:32             ` C H Forsyth
2004-02-29 21:10               ` boyd, rounin
2004-03-01  8:19                 ` Charles Forsyth
2004-03-01  8:46                   ` dbailey27
2004-03-01  9:34                     ` David Tolpin
2004-03-01 10:02                       ` Charles Forsyth
2004-03-01 10:12                         ` David Tolpin
2004-03-01 10:40                       ` Charles Forsyth
2004-03-01 11:56                         ` David Tolpin
2004-03-01 17:29                           ` rog
2004-03-02  6:38                         ` 9nut
2004-03-01 19:02                       ` Taj Khattra
2004-03-01 19:15                         ` David Tolpin
2004-03-01 19:22                           ` Joel Salomon
2004-03-01 19:43                             ` David Tolpin
2004-03-01 21:07                               ` Derek Fawcus
2004-03-01 21:12                                 ` David Tolpin
2004-03-02  2:46                                   ` boyd, rounin
2004-03-02  6:02                                     ` David Tolpin
2004-03-02 12:31                                       ` Bruce Ellis
2004-03-02 18:46                                         ` boyd, rounin
2004-03-02 12:19                                   ` Dick Davies
2004-03-02 18:40                                     ` boyd, rounin
2004-03-04  3:52                                     ` Martin C.Atkins
2004-03-04  9:07                                       ` Bruce Ellis
2004-03-01 21:15                                 ` Charles Forsyth
2004-03-01 21:20                                 ` rog
2004-03-02  2:48                                   ` Joel Salomon
2004-03-03  3:58                           ` Martin C.Atkins
2004-03-01  9:36                   ` Geoff Collyer
2004-03-01 12:06                     ` boyd
2004-03-01 14:55                       ` David Presotto
2004-03-01 12:18                   ` boyd
2004-03-01 13:29                     ` Fco.J.Ballesteros
2004-03-01 13:33                       ` lucio
2004-03-01 13:55                       ` boyd
2004-03-02  4:13                   ` Taj Khattra
2004-03-02  4:34                     ` Roman Shaposhnick
2004-03-02  4:47                       ` ron minnich
2004-03-02  5:53                         ` Roman Shaposhnick
2004-03-02  5:58                           ` ron minnich
2004-03-02 15:49                         ` boyd, rounin
2004-03-02  7:00                     ` rob pike, esq.
2004-03-02 20:58                       ` Andrew Simmons
2004-03-02 21:23                         ` boyd, rounin
2004-03-03  7:05                           ` Anastasopoulos S
2004-03-03  5:11                         ` Kenji Okamoto
2004-03-03  5:26                           ` boyd, rounin
2004-03-03  9:49                             ` Bruce Ellis
2004-03-03 12:41                               ` boyd, rounin
2004-03-03  9:42                           ` Bruce Ellis
2004-03-03  7:55                         ` 9nut
2004-02-27  6:59   ` Donald Brownlee
2004-02-27  7:49   ` boyd, rounin
2004-02-27 10:11 ` [9fans] " Douglas A. Gwyn
2004-02-28  5:20   ` Martin C.Atkins
2004-02-28  9:44     ` Nigel Roles
2004-02-28 11:08       ` viro
2004-02-28 13:40         ` Nigel Roles
2004-02-28 13:36           ` boyd, rounin
2004-02-28 14:14           ` viro
2004-02-28 18:16             ` Nigel Roles
2004-02-28 18:53               ` viro
2004-02-28 19:44                 ` Charles Forsyth
2004-02-28 20:13                   ` Rob Pike
2004-03-01 11:50                   ` viro
2004-03-01 11:49                     ` dbailey27
2004-02-28 13:32       ` boyd, rounin
2004-03-01 10:35         ` Douglas A. Gwyn
2004-03-01 11:01           ` Geoff Collyer
2004-03-01 19:13           ` Joel Salomon
2004-03-01 10:35       ` Douglas A. Gwyn
2004-02-28 13:41     ` David Presotto
     [not found] <20040227081500.14366.qmail@g.galapagos.bx.psu.edu>
2004-02-27  8:58 ` [9fans] " Linus Torvalds
     [not found] <a7ec3985c6aeabd43949005aa6af0f67@collyer.net>
2004-02-27  9:30 ` Linus Torvalds
2004-02-27  8:33   ` boyd, rounin
2004-02-27  9:52     ` Linus Torvalds
2004-02-27 12:14       ` Fco.J.Ballesteros
2004-03-02  4:48   ` Martin C.Atkins
2004-03-02  4:56     ` ron minnich
2004-03-02  9:42       ` Bengt Kleberg
     [not found] <dbcf45ba64ac8a77cd6a3dc6ba63b94b@plan9.escet.urjc.es>
2004-02-27 17:26 ` Linus Torvalds
2004-02-27 23:22   ` boyd, rounin
     [not found] <749601c045a56e4f77835f30907e255b@vitanuova.com>
2004-02-27 17:43 ` Linus Torvalds
     [not found] <f62d09b11d1f097b3f4b5f6b70b65ea5@proxima.alt.za>
2004-03-02  6:55 ` David Tolpin
2004-03-04  6:43 Andrew Simmons

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=Pine.LNX.4.58.0402270814250.2563@ppc970.osdl.org \
    --to=torvalds@osdl.org \
    --cc=9fans@cse.psu.edu \
    --cc=rob@mightycheese.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).