jr@oglvee.UUCP (Jim Rosenberg) (07/07/90)
Somewhere along in the development of System V, fork became an unreliable system call. At least it is on my (V.3) system. I asked the net about this, and after some completely wrong answers that we were out of swap space, the story that emerged was (to cite an old posting, Jerry Gardner in <3696@altos86.Altos.COM>): > The fork() failures you are seeing are occurring when procdup() calls > dupreg(). Dupreg() calls ptsalloc() which eventually calls getcpages() to > allocate memory for page tables to map the new child process' u-area. > Apparently, the kernel is paranoid in one place here and it calls ptsalloc > with a flag that doesn't allow it to sleep. Apparently if sleep were allowed a deadlock could occur. The result is that an intensive burst of activity can cause fork to fail, even though really the system is *not* out of resources and ought to be able to handle it. (Since the page-stealing daemon is asynchronous, you can never guarantee *exactly* when it will run.) Numerous people suggested more RAM as the cure. Right. What that amounts to saying is, "Get enough RAM so that you *NEVER* page." I.e. V.3 has virtual memory, but don't assume you can really use it. The number of utilities that both use fork and also understand that under some circumstances it ought to be *retried* if it fails is pitifully small. (The shell simply reports the bogus message "No more processes". On my system when cron incurs a fork failure it logs that it is "rescheduling" the job. Right. cron "reschedules" into oblivion, ceasing to run *any* jobs.) My question is: Is this *FIXED* in V.4? I went to the V.4 internals tutorial at Usenix in D.C. V.4 does have an asynchronous page-stealing daemon and does have a kernel memory allocate call with a flag to either sleep or not sleep. Do any of the kmem_alloc() calls (if I remember the name right, I don't have my notes handy) resulting from fork *not* allow sleep? If so I believe that would also give V.4 the lovely V.3 feature of unreliable fork. And in this I-hope-not case, the man page for fork(2) should at least tell the truth and make clear the circumstances under which fork should be retried. And all the utilities which fork should be hacked to actually do those retries. --- Jim Rosenberg #include <disclaimer.h> --cgh!amanue!oglvee!jr Oglevee Computer Systems / / 151 Oglevee Lane, Connellsville, PA 15425 pitt! ditka! INTERNET: cgh!amanue!oglvee!jr@dsi.com / /
gwyn@smoke.BRL.MIL (Doug Gwyn) (07/08/90)
In article <561@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: >The number of utilities that both use fork and also understand that under >some circumstances it ought to be *retried* if it fails is pitifully small. This is unfortunately true, but then so is the number of utilities that understand that write() might successfully write fewer than the requested number of bytes. >(The shell simply reports the bogus message "No more processes". Actually, the UNIX System V shells that I've encountered do keep retrying the fork() operation for a while. In fact, somewhere around SVR2.0 the shell was changed to use an "exponential backoff" algorithm, i.e. the delay between successive retries was doubled each time until some limit was hit, at which time the shell would give up with "No more processes". This algorithm, combined with a too-small per-user process limit, was directly responsible for some UNIX System V vendors failing to pass the operational demonstration in the large DA MINIS acquistion; because all the "batch" scripts were executed under the same UID, several of them quickly backed off to the point that they did not start running very soon after the heavy load had subsided; basically the machine was idle and the shells were sleeping like Rip van Winkle.
jr@oglvee.UUCP (Jim Rosenberg) (07/09/90)
gwyn@smoke.BRL.MIL (Doug Gwyn) writes: >In article <561@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: >>(The shell simply reports the bogus message "No more processes". >Actually, the UNIX System V shells that I've encountered do keep retrying >the fork() operation for a while. In fact, somewhere around SVR2.0 the >shell was changed to use an "exponential backoff" algorithm, i.e. the >delay between successive retries was doubled each time until some limit >was hit, at which time the shell would give up with "No more processes". Fascinating. I don't think we're seeing this behavior, but all of our users are either taken straight to our database manager sans shell by .profile or use csh. I bet the exponential backoff was *not* put into csh. This is V.3.1. I don't know when AT&T officially held its nose and blessed csh as a "real" shell, but my impression is that it wasn't until V.3.2. Does csh under V.4 have the exponential backoff? I presume under BSD no such thing is needed. -- Jim Rosenberg #include <disclaimer.h> --cgh!amanue!oglvee!jr Oglevee Computer Systems / / 151 Oglevee Lane, Connellsville, PA 15425 pitt! ditka! INTERNET: cgh!amanue!oglvee!jr@dsi.com / /
mab@druwy.ATT.COM (Alan Bland) (07/10/90)
In article <561@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: >The number of utilities that both use fork and also understand that under >some circumstances it ought to be *retried* if it fails is pitifully small. fork(2) isn't the only System V call that needs to be retried under some circumstances. poll(2) is another one that can fail with EAGAIN, which means it may work if you try again. There are also others -- pay attention to the errno descriptions in the programmers reference guide. -- -- Alan Bland -- att!druwy!mab == mab@druwy.ATT.COM -- AT&T Bell Laboratories, Denver CO -- (303)538-3510
gwyn@smoke.BRL.MIL (Doug Gwyn) (07/12/90)
In article <563@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: >Fascinating. I don't think we're seeing this behavior, ... I'm not sure you understood what I was describing. You would only see that when fork()s started to fail, and that normally occurs only when the user reaches his process-count limit, which is a system configuration parameter. The reason this occurred in the operational demo that I described is that the vendor chose to set up all accounts being used for the test with the same UID, thereby virtually assuring that the process limit would be encountered. Normal use of UNIX does not have everybody operating under the same UID. >Does csh under V.4 have the exponential backoff? I presume under BSD no >such thing is needed. It has nothing to do with "BSD vs. SysV". Any system with a bound on the number of processes permitted for a given user would encounter fork() failures (which could of course also occur if the system ran out of space resources). I hope my example made it clear why exponential backoff was a poor strategy. However, most shells should attempt to recover from fork() failures to a reasonable degree.
lls@kings.co.uk (Lady Lodge Systems) (07/13/90)
In article <561@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: >Somewhere along in the development of System V, fork became an unreliable >system call.... >... >The number of utilities that both use fork and also understand that under >some circumstances it ought to be *retried* if it fails is pitifully small. >(The shell simply reports the bogus message "No more processes"... Or if you are using the command substitute construct (...`run cmd`...) and the Bourne shell cannot fork it simply hangs. No retry, No Error just a full stop! Sheesh! if the shell is broken about retrying forks, is it any wonder that most other programs are as well? >My question is: Is this *FIXED* in V.4? Damned Good Question! -- ------------------------------------------------------------------------- | Peter King. | Voice: +44 733 239445 | | King Bros (Lady Lodge) Ltd | EMAIL: root@kings.co.uk | | Lady Lodge House, Orton Longueville, | UUCP: ...mcvax!ukc!kings!root | | Peterborough, PE2 0HZ, England. | | -------------------------------------------------------------------------
jr@amanue.UUCP (Jim Rosenberg) (07/25/90)
In <32@kings.co.uk> lls@kings.co.uk (Lady Lodge Systems) writes: >In article <561@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: >>Somewhere along in the development of System V, fork became an unreliable >>system call.... >>My question is: Is this *FIXED* in V.4? >Damned Good Question! Which, alas, no one has answered. Surely *somebody* reading this group can look at the V.4 source and let us know. To repeat: do any kernel routines called as result of a fork issue kmem_alloc() with the flag KM_NOSLEEP? If the answer is yes then it would seem to me V.4 will have the same problem as V.3. -- Jim Rosenberg -- cgh!amanue!jr CIS: 71515,124 UUCP: / / | WELL: jer dsi.com pitt! ditka! BIX: jrosenberg Internet: cgh!amanue!jr@dsi.com
ag@cbmvax.commodore.com (Keith Gabryelski) (07/25/90)
In article <480@amanue.UUCP> jr@amanue.UUCP (Jim Rosenberg) writes: >In article <561@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: >>Somewhere along in the development of System V, fork became an >>unreliable system call.... Unreliable in what way? fork() has always been documented to fail if there isn't enough system resources. Forgive me, I haven't been keeping up with c.u.w. >>My question is: Is this *FIXED* in V.4? > >Which, alas, no one has answered. Surely *somebody* reading this >group can look at the V.4 source and let us know. To repeat: do any >kernel routines called as result of a fork issue kmem_alloc() with >the flag KM_NOSLEEP? If the answer is yes then it would seem to me >V.4 will have the same problem as V.3. When assigning a process id the kernel will try to allocate a proc_t without sleeping [ie, pass KMEM_NOSLEEP to *alloc()]. If this fails, fork() will return EAGAIN. What isn't reasonable about this? fork() is documented (under SVR4) to fail returning EAGAIN if: The system-imposed limit on the total number of processes under execution by a single user would be exceeded. or Total amount of system memory available when reading via raw I/O is temporarily insufficient. Although I don't know of any other unix varient that documents the latter case (save SVR3), EAGAIN is a totally reasonable thing to check for as a return error code from fork(). Pax, Keith
jr@oglvee.UUCP (Jim Rosenberg) (07/27/90)
In <13426@cbmvax.commodore.com> ag@cbmvax.commodore.com (Keith Gabryelski) writes: >>In article <561@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: >>>Somewhere along in the development of System V, fork became an >>>unreliable system call.... >Unreliable in what way? fork() has always been documented to fail >if there isn't enough system resources. *** OPEN DRAGON MOUTH *** What do you count as a resource? Disk space is a resource. If I run out of swap space, I'm the system administrator, this is *my* problem, I don't go complaining to Dennis Ritchie because I don't have a rubber disk. I also *can fix it*. It isn't fun, but I can reconfigure my disk for more swap space. Is physcial memory a resource? Now it gets sticky. The whole concept of virtual memory is exactly supposed to be that I SHOULDN'T HAVE TO think of physical memory as a resource; the operating system should handle that, as long as what I'm asking for is reasonable. If my system is so loaded that there are no more process table slots, again, as system administrator that's *my* problem. And I can fix it. But if system calls fail simply because of a very temporary bout of activity, that is *not my problem*! It's the kernel's problem. At least it should be: that's what "I'm paying the kernel for" so to speak. And *I CAN'T FIX IT* myself. If utilities haven't been rewritten to do the right thing with EAGAIN after fork(), and I'm only a binary licensee, what can I do about it? (Except climb the soap box in this newsgroup, of course! :-)) >When assigning a process id the kernel will try to allocate a proc_t >without sleeping [ie, pass KMEM_NOSLEEP to *alloc()]. If this fails, >fork() will return EAGAIN. OK, so we have the word, V.4 will have some of the same problems as V.3. >What isn't reasonable about this? fork() is documented (under SVR4) >to fail returning EAGAIN if: [citation from the man page for fork(2)] Come on now. How many times have you seen a writeup on how to do things with fork() in a UNIX magazine or book -- and how many of those times has the author done *ANYTHING* at all with EAGAIN?? It is simply a fact that the need to retry forks that have failed with EAGAIN is not widely embedded out there in UNIX culture. I have not seen one single writeup in print that really discusses this. My favorite text on programming UNIX system calls is Marc Rochkind's book, Advanced UNIX Programming. Maybe I have an old edition, but here's what he says about it: "The only cause of an error is resource exhaustion, such as insufficient swap space or too many processes already in execution." No mention of the fact that if you just wait for the page- stealing daemon to go to work everything will be fine. Is it "reasonable" for my application to have to sleep when in fact it should be the kernel that does the sleep for me? Why should I have to guess how long to sleep? My application doesn't have to sleep to wait for a disk block to become available -- the kernel does this for me. Why shouldn't it do the same thing for memory pages? What retry policy should one use? How long should one sleep? How many retries? Or even a larger question: How come there's no consensus on this? How come this isn't one of those FrequentlyAskedQuestions? Does every V.4 utility that forks in fact *do something sensible* with EAGAIN? (Since having the application deal with this is so "reasonable" ...) Once again, those of you out there with source can answer this one easily enough. The larger question is *why can't the kernel sleep* when it needs more memory for a fork??? It appears there is a risk of some kind of deadlock. Whose problem is *this*? Mine as system administrator? When I brought this subject up the first time, someone posted that they had, in fact, hacked their source code to allow sleep under V.3. This person said he got away with it. That leads me to believe that in fact he was simply lucky, but that the race condition or deadlock or whatever the problem is is mighty obscure. Perhaps too obscure for anyone to *FIX*. My personal view is that a kernel whose only mutual exclusion mechanisms are sleep-wakeup and spl() just makes it too complicated to really fix this and allow sleep. Once upon a time there was a consensus that the kernel needed to be rewritten from scratch. Once upon a time there was the famous V.5 skunk works doing exactly this, and based on what Bill Joy told me once it sounds like it would have dealt with this kind of problem. But then the skunk works became politically untenable after the OSF rebellion, so now we seem not to hear much talk about how important it is to rewrite the kernel. (Except from OSF, CMU, who say they've already done it ... :-)) We only hear talk that it is "reasonable" to bother the application with the fact that the system just happens to be kind of busy at the moment, but busy with a problem on which it *should* be able to sleep ... And for those of you wizards out there who write articles on C for such mags as UNIX Review & UNIX World, please **TELL PEOPLE** about this issue! -- Jim Rosenberg #include <disclaimer.h> --cgh!amanue!oglvee!jr Oglevee Computer Systems / / 151 Oglevee Lane, Connellsville, PA 15425 pitt! ditka! INTERNET: cgh!amanue!oglvee!jr@dsi.com / /
gwyn@smoke.BRL.MIL (Doug Gwyn) (07/28/90)
In article <573@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes:
-But if system calls fail simply because of a very temporary bout of activity,
-that is *not my problem*! It's the kernel's problem. At least it should be:
-that's what "I'm paying the kernel for" so to speak. And *I CAN'T FIX IT*
-myself. If utilities haven't been rewritten to do the right thing with EAGAIN
-after fork(), and I'm only a binary licensee, what can I do about it?
Oh, good grief. It is SILLY to say that the kernel should be redesigned
to compensate for bugs in application programs.
terryl@sail.LABS.TEK.COM (07/28/90)
In article <573@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: >In <13426@cbmvax.commodore.com> ag@cbmvax.commodore.com (Keith Gabryelski) writes: >>>In article <561@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: >>>>Somewhere along in the development of System V, fork became an >>>>unreliable system call.... >>Unreliable in what way? fork() has always been documented to fail >>if there isn't enough system resources. > >*** OPEN DRAGON MOUTH *** > Delete MANY, MANY lines of bitching and moaning about why the "kernel" should sleep if system resources can't be found for a fork, instead of just returning an error condition.... >My personal view is that a kernel whose only mutual exclusion mechanisms are >sleep-wakeup and spl() just makes it too complicated to really fix this and >allow sleep. Once upon a time there was a consensus that the kernel needed to >be rewritten from scratch. Once upon a time there was the famous V.5 skunk >works doing exactly this, and based on what Bill Joy told me once it sounds >like it would have dealt with this kind of problem. But then the skunk works >became politically untenable after the OSF rebellion, so now we seem not to >hear much talk about how important it is to rewrite the kernel. (Except from >OSF, CMU, who say they've already done it ... :-)) > >We only hear talk that it is "reasonable" to bother the application with the >fact that the system just happens to be kind of busy at the moment, but busy >with a problem on which it *should* be able to sleep ... Well, there's a couple of reasons why "it is reasonable to bother the application" with the fact that system resources are a little scarce, and could you try your request again later???? These reasons go WAY BACK (we're talking ancient history here, boys and girls!!! (-:), and are some of the philosophies espounded by Ritchie, Thompson, Kernighan, et. al. (hope I spelled their names right!!! (-:). The first is "KISS" (Keep It Simple, Stupid). Don't clutter up the code with obscure and esoteric algorithms when a simpler one will do; makes the code easier to maintain, and mucho easier to understand. Unfortunately, with the sophistication of today's hardware, it is becoming increasingly difficult to "KISS" (pun intended!!! (-:). A direct corollary of "KISS" is thus: It is better to make 20 programs each do one thing well, than it is to make one program do 20 things. Not only is it better, it is also easier, and promotes modularity and re-use of compo- nents. Unfortunately, this concept has long since been abandoned MANY, MANY moons ago, and I for one am sad to see it go (I submit the options of `cat' and `ls' as prime examples; I'm sure astute readers can think of their favorite examples of this...). The second reason is thus: for the most part, the "kernel" should NOT impose policy; it should be up to the individual application to impose it's policy that it wants. If the "kernel" were to impose policy, it would limit the application's choices, which Ritchie, et. al. decided "is a bad thing to do". The "kernel" should be thought of as mainly a "system resource manager", with just enough policy to make things work. The file system is an excellent axample of this. As far as the "kernel" is concerned, files are just a sequence of bytes; the "kernel" makes no assumptions on what these sequences of bytes really means. It is up to the application to determine what these means (OK, yes, there are a COUPLE of places where the "kernel" knows a priori what these bytes mean, e.g. an executable header...). So, for Mr. Rosenberg's assertion that "the kernel SHOULD sleep on a resource shortage", this is imposing a policy upon the application that is better left to the application. BTW, this is all IMHO, etc., and if I've misrepresented Mr. Ritchie's position, apologies in advance, etc.... Terry Laskodi of Tektronix
sar0@cbnewsl.att.com (stephen.a.rago) (07/28/90)
In article <480@amanue.UUCP>, jr@amanue.UUCP (Jim Rosenberg) writes: > In <32@kings.co.uk> lls@kings.co.uk (Lady Lodge Systems) writes: > > >In article <561@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: > >>Somewhere along in the development of System V, fork became an unreliable > >>system call.... > > >>My question is: Is this *FIXED* in V.4? > > Which, alas, no one has answered. Surely *somebody* reading this group can > look at the V.4 source and let us know. To repeat: do any kernel routines > called as result of a fork issue kmem_alloc() with the flag KM_NOSLEEP? Yes.
peter@ficc.ferranti.com (Peter da Silva) (07/28/90)
In article <573@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: > The larger question is *why can't the kernel sleep* when it needs more memory > for a fork??? Even if it can't do it right then, it could check right before leaving kernel mode. Or if that's politically incorrect, change fork.o in libc.a to implement the check for EAGAIN and do an exponential backoff (or whatever). -- Peter da Silva. `-_-' +1 713 274 5180. 'U` <peter@ficc.ferranti.com>
martin@mwtech.UUCP (Martin Weitzel) (07/29/90)
In article <13435@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) writes: >In article <573@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: >-But if system calls fail simply because of a very temporary bout of activity, >-that is *not my problem*! It's the kernel's problem. At least it should be: >-that's what "I'm paying the kernel for" so to speak. And *I CAN'T FIX IT* >-myself. If utilities haven't been rewritten to do the right thing with EAGAIN >-after fork(), and I'm only a binary licensee, what can I do about it? > >Oh, good grief. It is SILLY to say that the kernel should be redesigned >to compensate for bugs in application programs. Would you write the same, if someone sold a disk controller with a firmware problem that causes it sometimes to give erratic answers, until, say, the head happens to cross track 512, after which everthing runs normal again? Suppose further this erratic behaviour is even documented somewhere in the controller manual. Would you support the view of the controller manufacturer who might say: "In fact, my controller is working PERFECTLY WELL, it's all the problem of those who haven't read the docs which tells about this. It's SILLY to say I should redesign the firmware to compensate for bugs in device drivers of UNIX, which should just make more retries if this particular problems shows up. As the DOS-driver I supply with my controller shows, there's no problem with my controller if you use it in the right way." Well, if I put myself in the shoes of that particular manufacturer, I could even take this view. If I put myself into the shoes of a kernal code developper, I can well understand Doug Gwyn's view (and from the many knowledgable answers and worthful contributions Doug has posted to this group, I think his view *is* the one of a person who knows kernal stuff more than well). But I'm in the position of an application developper and as such I take the view of the original poster, who's opinion is that a solution for this problem belongs into the kernal. Oh ... wait a moment, my telephone just rings ... "Who's there, Joe Customer? What, the program I sold you behaves erratic. Ehmm, just retry some times ... and btw. read the docs. On page 277 you'll find a footnote that tells you that you should just retry ...". OK, here I'm back again. Oh folks, these SILLY customers! They allways want me to redesign this complex program, just because they can't use it in the right way ... :-) -- Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83
jfh@rpp386.cactus.org (John F. Haugh II) (07/30/90)
In article <ZOY4ZO4@xds13.ferranti.com> peter@ficc.ferranti.com (Peter da Silva) writes: >In article <573@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: >> The larger question is *why can't the kernel sleep* when it needs more memory >> for a fork??? >Even if it can't do it right then, it could check right before leaving >kernel mode. Or if that's politically incorrect, change fork.o in libc.a >to implement the check for EAGAIN and do an exponential backoff (or >whatever). It isn't that the kernel =can't= sleep, but rather that someone decided [ for some totally random reason, I suspect ... ] that the kernel =shouldn't= sleep. The solution isn't to add some kludge on top of the system, but rather to put back the behavior that was always there - the kernel sleeps in fork if it requires additional memory. In the past, the kernel swapped the process if malloc() didn't return with space. So, this is a change in function, not some defect in application code. -- John F. Haugh II UUCP: ...!cs.utexas.edu!rpp386!jfh Ma Bell: (512) 832-8832 Domain: jfh@rpp386.cactus.org
friedl@mtndew.UUCP (Stephen J. Friedl) (07/30/90)
In article <18478@rpp386.cactus.org>, jfh@rpp386.cactus.org (John F. Haugh II) writes: > > It isn't that the kernel =can't= sleep, but rather that someone decided > [ for some totally random reason, I suspect ... ] that the kernel > =shouldn't= sleep. The solution isn't to add some kludge on top of the > system, but rather to put back the behavior that was always there - > the kernel sleeps in fork if it requires additional memory. I've been following this and am not so sure I agree with this line of thinking. What if I >want< fork to fail if it can't do it (because I want to reschedule the process that wants to fork for a later time). By allowing the calling program control right away, it can make its own choice. If you put this in the kernel then everybody does it the same way: how long should it wait before giving up? Wkat kind of backoff should it use? Steve -- Stephen J. Friedl, KA8CMY / Software Consultant / Tustin, CA / 3B2-kind-of-guy +1 714 544 6561 / friedl@mtndew.Tustin.CA.US / {uunet,attmail}!mtndew!friedl "I'm a simple girl; I wear a cat on my head." - Laura Dykstra @ NCR Orlando
terryl@sail.LABS.TEK.COM (08/01/90)
In article <573@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes:
-But if system calls fail simply because of a very temporary bout of activity,
-that is *not my problem*! It's the kernel's problem. At least it should be:
-that's what "I'm paying the kernel for" so to speak. And *I CAN'T FIX IT*
-myself. If utilities haven't been rewritten to do the right thing with EAGAIN
-after fork(), and I'm only a binary licensee, what can I do about it?
Bitch and moan to your OS vendor; after all, to use some of your own
logic, "That's what I'm paying the kernel for", so to speak....
ag@cbmvax.commodore.com (Keith Gabryelski) (08/01/90)
In article <ZOY4ZO4@xds13.ferranti.com> peter@ficc.ferranti.com (Peter da Silva) writes: >In article <573@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: >>The larger question is *why can't the kernel sleep* when it needs >>more memory for a fork??? > >Even if it can't do it right then, it could check right before leaving >kernel mode. Or if that's politically incorrect, change fork.o in libc.a >to implement the check for EAGAIN and do an exponential backoff (or >whatever). Or fix the application program. Pax, Keith
peter@ficc.ferranti.com (Peter da Silva) (08/02/90)
Isn't the problem that EAGAIN is being overloaded for two purposes: out of process table space (likely long-term on the time-scale programs operate, and should be an error *for most programs*) and out of memory (likely short term, so you should back off and try again)? Since only the kernel can distinguish these two cases, it should be the one to implement the retry (like, if fork failed because it couldn't get the buffer don't drop all the way to system mode: allocate a block and when you get it then you redo the fork... with the allocated block at hand so it can't fail). -- Peter da Silva. `-_-' +1 713 274 5180. 'U` <peter@ficc.ferranti.com>
jr@oglvee.UUCP (Jim Rosenberg) (08/02/90)
In <18478@rpp386.cactus.org> jfh@rpp386.cactus.org (John F. Haugh II) writes: >>In article <573@oglvee.UUCP> jr@oglvee.UUCP (Jim Rosenberg) writes: >>> The larger question is *why can't the kernel sleep* when it needs more memory >>> for a fork??? >It isn't that the kernel =can't= sleep, but rather that someone decided >[ for some totally random reason, I suspect ... ] that the kernel >=shouldn't= sleep. I agree with the sentiments 100%, obviously, but I fear life is not so simple. >In the past, the kernel swapped the process if malloc() didn't return >with space. So, this is a change in function, not some defect in >application code. But that was in swapping days, before V.3's hideous virtual memory. Historically the kernel has never multitasked internally. But somewhere along the way, System V acquired "kernel daemons" -- in spite of lacking generalized internal primitives for synchronizing true threads. As I understand it, to this day the only ways to synchronize flow of execution in the kernel are sleep/wakeup and spl (disabling interrupts.) These are *not good enough* for generalized thread support. Wakeups can be lost, as opposed ups on a semaphore. Somebody decided that the dirty work of moving reclaimable memory pages to swap space could be handled by an asynchronous "kernel daemon". Now just exactly HOW, without generalized thread support, is this daemon to be synchronized with the part of the kernel that needs the memory when you fork? The answer, apparently, is that they are synchronized only by that arcane black magic that has come to surround the kernel. You just have to "know" what you can get away with to avoid deadlock and race conditions, and when you can't avoid them you throw out the door "the functionality that used to be there" to paraphrase John. *THIS* is the reason for rewriting the kernel: In <13435@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) writes: > Oh, good grief. It is SILLY to say that the kernel should be redesigned > to compensate for bugs in application programs. Lighten up, Doug. Some mighty heavy folks thought the kernel *needed* threads. I'd love to see some of the folks who've been lecturing me on KISS and policy and whatnot say those things to the people who *were working* on V.5 -- which *did have* kernel threads. The V.5 project was not stopped (was it stopped? :-)) for technical reasons but for political reasons. Are the technical reasons that got it started suddenly wrong? I am truly mortified that **NO ONE** has posted an explanation of just what the deadlock would be if the kernel did allow sleep in allocating memory for a fork. I fear no one understands it any more. Dammit, Doug, it's not that I'm too lazy to read a man page or to rewrite my fork code to do the right thing. The point I'm making is that this functionality which we've lost since swapping days is but the tip of a future iceberg. The kernel *can* sleep on the availability of a block in the buffer cache. (Yeah, I know, there is no more buffer cache in V.4, VM does it all ...) If the page stealing daemon and the "main part" of the kernel could communicate properly, using something better than sleep/wakeup, then perhaps the kernel *could sleep* on the availability of a memory page. John & I & other folks are saying that we thought this was the sort of thing kernels were supposed to be able to do. They could once. (BSD still can?) If the System V kernel could, it would be a better kernel. And now folks are talking about bolting symmetric multiprocessing onto this ballooning kernel. If we can't get a clear explanation of just what the issue is as to why the kernel can't sleep on more memory for a fork, what's going to happen when all this is running on multiple processors? Since I've provoked a good deal of theological spouting, I can't resist asking what happened to the old idea that UNIX was supposed to be *understandable*? Meantime, if architects think they can get away with kernel threads without full support for it, and us consumers of UNIX point out that by golly they didn't really quite get away with it, hey, it's our bucks, we're entitled. When I found that V.4, like V.3, uses an asynchronous page-stealing daemon, it made me nervous. I'm still nervous. -- Jim Rosenberg #include <disclaimer.h> --cgh!amanue!oglvee!jr Oglevee Computer Systems / / 151 Oglevee Lane, Connellsville, PA 15425 pitt! ditka! INTERNET: cgh!amanue!oglvee!jr@dsi.com / /
dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) (08/04/90)
All the applications programs that I know of assume that that there is no point retrying a failed fork(). I've seen quite a few books about programming in a UNIX environment, and I don't recall seeing a recommendation that a failed fork() be retried. (Yet authors usually warn that a failed write() may succeed, and that a failed read() for some types of descriptors should always be retried.) So it seems that if fork() can fail but be likely to succeed if retried, either AT&T needs to hold a MASSIVE publicity campaign telling all these people (including its own staff programmers, who sometimes write books and articles about UNIX programming) that they have been writing buggy code all these years; OR it needs to modify its kernel. -- Rahul Dhesi <dhesi%cirrusl@oliveb.ATC.olivetti.com> UUCP: oliveb!cirrusl!dhesi
sar0@cbnewsl.att.com (stephen.a.rago) (08/04/90)
In article <575@oglvee.UUCP>, jr@oglvee.UUCP (Jim Rosenberg) writes: [much rambling deleted...] > I am truly mortified that **NO ONE** has posted an explanation of just what > the deadlock would be if the kernel did allow sleep in allocating memory for a > fork. There is a deadlock if the kernel had to wait for proc slots, because if all the processes were trying to fork, and nobody intended to exit, then every process (except the kernel procs and init) would be waiting indefinitely in the kernel for an event that would never occur. However, the same deadlock is still possible when you kmem_alloc(KM_SLEEP) a proc structure, only it's a lot less likely to occur because the memory can be coming from other places (like STREAMS messages, etc.) The only time you'll deadlock is when no more memory is available and everyone is waiting to allocate the space for their own proc structure. Steve Rago sar@attunix.att.com
als@bohra.cpg.oz (Anthony Shipman) (08/07/90)
At the risk of getting in out of my depth! In article <575@oglvee.UUCP>, jr@oglvee.UUCP (Jim Rosenberg) writes: > I am truly mortified that **NO ONE** has posted an explanation of just what > the deadlock would be if the kernel did allow sleep in allocating memory for a > fork. I fear no one understands it any more. Dammit, Doug, it's not that I'm There could be a deadlock between user level processes. Suppose a process has used lots of kernel memory eg with file locks, open files, open inodes etc and then sleeps on more memory. Then another such process does the same thing. They could end up deadlocked. Since shortage of kernel memory is a critical thing and these deadlocked processes have tied up lots of it the problem could spread. A standard simple "naive" solution to break the deadlock is to kill one of the processes at the request point. In this case, make the fork() fail. If several retries fail then abort the program (and release memory). An indefinite wait would be dangerous. Of course this principle would have to be applied to every system call. Other deadlock protection methods over general user processes are probably inapplicable. > the availability of a block in the buffer cache. (Yeah, I know, there is no The memory for buffers is preallocated at system boot time. > Meantime, if architects think they can get away with kernel threads without > full support for it, and us consumers of UNIX point out that by golly they > didn't really quite get away with it, hey, it's our bucks, we're entitled. > When I found that V.4, like V.3, uses an asynchronous page-stealing daemon, it > made me nervous. I'm still nervous. And I'm bitten. My SCO UNIX 3.2 machine (appears to) deadlock frequently on going virtual (using the swap space for the first time). -- Anthony Shipman ACSnet: als@bohra.cpg.oz.au Computer Power Group 9th Flr, 616 St. Kilda Rd., St. Kilda, Melbourne, Australia D
jfh@rpp386.cactus.org (John F. Haugh II) (08/08/90)
In article <553@bohra.cpg.oz> als@bohra.cpg.oz (Anthony Shipman) writes: >A standard simple "naive" solution to break the deadlock is to kill one of the >processes at the request point. In this case, make the fork() fail. If several >retries fail then abort the program (and release memory). An indefinite wait >would be dangerous. I'm quite pleased to state the AIX V3.1 does not have this same problem which AT&T has decided to introduce. Not only does their fork() not fail for transient shortages of real memory, but it has the added complexity of working in an environment where almost all system calls are pre-emptable, and frequently =are= pre-empted, page faulted, put to sleep, and a half dozen other evils. For more information on the implementation of the AIX kernel, please see "Enhancements to the AIX Kernel for Support of Real-Time Applications", by Kathy A. Bohrer and John T. O'Quin, IBM publication SA23-2619. -- John F. Haugh II UUCP: ...!cs.utexas.edu!rpp386!jfh Ma Bell: (512) 832-8832 Domain: jfh@rpp386.cactus.org
boyd@necisa.ho.necisa.oz (Boyd Roberts) (08/09/90)
In article <553@bohra.cpg.oz> als@bohra.cpg.oz (Anthony Shipman) writes: >At the risk of getting in out of my depth! > > [stuff deleted] > >A standard simple "naive" solution to break the deadlock is to kill one of the >processes at the request point. In this case, make the fork() fail. If several >retries fail then abort the program (and release memory). An indefinite wait >would be dangerous. > NO, NO, NO! You do not _understand_. _Never_ do that. NEVER! Which proc will you kill? And when (if ever) will it run so it can exit()? It's very simple. When you're low on ram & swap and processes are fighting for this resource there's bugger all you can do. Sure you can purge a few sticky texts but in a pathological case you run out of resources and there is nothing you can do. What is required are pre-emptive measures, such as: * memory limits * working set limits * warn that resources are about to expire (say 90% consumed) With these things a human can make decisions that will best serve the system's purpose. You've only got so much cake so you'd better choose well how it will best be eaten. Prevent the disaster from happening and then you won't have to code in disaster recovery. Boyd Roberts boyd@necisa.ho.necisa.oz.au ``When the going gets wierd, the weird turn pro...''
junk1@cbnews.att.com (eric.a.olson) (08/10/90)
In article <2123@cirrusl.UUCP> dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes: >All the applications programs that I know of assume that that there is >no point retrying a failed fork(). I've seen quite a few books about >programming in a UNIX environment, and I don't recall seeing a >recommendation that a failed fork() be retried. Ummm.... well, just why do you think the errno is called 'EAGAIN' ?