Live data from Hacker News

Why isn't memset() async-signal-safe?

boston.conman.org

61–70 of 98 posts

Re: Why isn't memset() async-signal-safe?

#61
post #51

Returning from the signal handler occurs in user space. It's the C library's handling of signal save and return that matters here, not what the kernel does.

So what does the sigreturn(2) syscall actually do?

I herby claim that sigreturn() restores the user space state in kernel context: https://lwn.net/Articles/676803/

Re: Why isn't memset() async-signal-safe?

#62

This article seems flat out wrong. Since the direction flag is correctly saved and restored, everything is cool. When some code is interrupted and the signal or interrupt handler calls memmove, that memmove will set up the direction flag for itself correctly. Its entire execution is nested within the handler. If it is interrupted by a nested interrupt, that nested one will restore the flag. Now if an implementation o…

Also, POSIX explicitly requires memcpy and memmove to be async-signal-safe. Claiming they are not is misinformation. The list of async-signal-safe functions is available here: http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2...

Odd, 'man 7 signal' (http://man7.org/linux/man-pages/man7/signal.7.html) does not list memcpy or memmove in the list of safe functions.

Re: Why isn't memset() async-signal-safe?

#63
post #18

Earlier quoted context omitted.

The more state you save, the larger the latency in handling the interrupt. And the amount of state in modern CPUs can be quite large indeed.

Any idea how much it is? (just as a guess, I'd guess like maybe 8 KiB?)

Show your work.

Re: Why isn't memset() async-signal-safe?

#64
post #63

Earlier quoted context omitted.

Any idea how much it is? (just as a guess, I'd guess like maybe 8 KiB?)

Show your work.

I don't remember how many there were for AVX, but let's say there are 8 512-bit registers (4 KiB)? and then equivalent in other kinds of registers, so 8 KiB. Just an order-of-magnitude estimate, nothing I expect to be too accurate.

Re: Why isn't memset() async-signal-safe?

#65
post #24

Couple of things. First, I don't think that's true nowadays. The discussion points that this (not restoring DF on signal return) is a kernel bug and should be fixed: https://lkml.org/lkml/2008/3/5/531 Second, the kernel tries to avoid doing too much work in the signal return code. It tries hard do _avoid_ heavy XSAVE and just preserve only the needed registers. This is the job of sigreturn(2) syscall btw. http://man7…

The site is down again? What's wrong with that site? A while back when I wanted to look something up in the x86_64 ABI the site was down too, for at least a week (I eventually gave up checking). At some point later it came back. I wonder how long it's been down this time.

Interestingly, Xcode's OS X docs used to link to x86-64.org for the AMD64 ABI, but looking right now, the link is removed (but the text remains), I guess because the site was down for so long.

Re: Why isn't memset() async-signal-safe?

#66
post #61
post #51

Returning from the signal handler occurs in user space. It's the C library's handling of signal save and return that matters here, not what the kernel does.

So what does the sigreturn(2) syscall actually do? I herby claim that sigreturn() restores the user space state in kernel context: https://lwn.net/Articles/676803/

You're right; "sigreturn" wasn't in early UNIX systems but appeared in 4.3BSD. That job can also be done in user space, but there's a timing window against other signals if done that way.

Re: Why isn't memset() async-signal-safe?

#67
post #62

Earlier quoted context omitted.

Also, POSIX explicitly requires memcpy and memmove to be async-signal-safe. Claiming they are not is misinformation. The list of async-signal-safe functions is available here: http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2...

Odd, 'man 7 signal' ( http://man7.org/linux/man-pages/man7/signal.7.html ) does not list memcpy or memmove in the list of safe functions.

It appears that memset() was only added in 2016.

Re: Why isn't memset() async-signal-safe?

#68
post #63

Earlier quoted context omitted.

Show your work.

I don't remember how many there were for AVX, but let's say there are 8 512-bit registers (4 KiB)? and then equivalent in other kinds of registers, so 8 KiB. Just an order-of-magnitude estimate, nothing I expect to be too accurate.

I'm also not an expert, but I think the bigger cost here is memory latency. Size correlates to, but scales differently than the switching cost of registers because it's zero sum. A register saved is a register waited on, twice. There's also the cost of decoding and executing the instructions to store / restore the register values on both ends.

Re: Why isn't memset() async-signal-safe?

#69
post #68

Earlier quoted context omitted.

I don't remember how many there were for AVX, but let's say there are 8 512-bit registers (4 KiB)? and then equivalent in other kinds of registers, so 8 KiB. Just an order-of-magnitude estimate, nothing I expect to be too accurate.

I'm also not an expert, but I think the bigger cost here is memory latency. Size correlates to, but scales differently than the switching cost of registers because it's zero sum. A register saved is a register waited on, twice. There's also the cost of decoding and executing the instructions to store / restore the register values on both ends.

I don't get it, you have to save and restore all the state on context switches either way. The only question is whether you're doing it with a generic instruction or through some other more specialized instructions. It's not a question of whether they should be saved and restored at all.

That said, I'm confused why you replied to my comment above, since it's totally off-topic. This thread chain was asking how much state exists; maybe you were trying to reply to another thread?

Re: Why isn't memset() async-signal-safe?

#70
post #33

Earlier quoted context omitted.

An OS can still use xsave incorrectly, such as by hardcoding the expected size rather than detecting it at runtime, or by getting some aspect of the CPUID leaf 0xd enumeration wrong. I wouldn't find it surprising if an initial implementation got one of the details wrong, resulting in a bug that wouldn't manifest until the next time the xsave layout changed.

The CPU designers could have protected against this by randomly fluctuating the size of the xsave'd data.

At the cost of extra bandwidth and interrupt latency.
Post reply on HN