#
e75baa28 |
| 21-Aug-2011 |
Attilio Rao <attilio@FreeBSD.org> |
callout_cpu_switch() allows preemption when dropping the outcoming callout cpu lock (and after having dropped it). If the newly scheduled thread wants to acquire the old queue it will just spin forev
callout_cpu_switch() allows preemption when dropping the outcoming callout cpu lock (and after having dropped it). If the newly scheduled thread wants to acquire the old queue it will just spin forever.
Fix this by disabling preemption and interrupts entirely (because fast interrupt handlers may incur in the same problem too) while switching locks.
Reported by: hrs, Mike Tancsa <mike AT sentex DOT net>, Chip Camden <sterling AT camdensoftware DOT com> Tested by: hrs, Mike Tancsa <mike AT sentex DOT net>, Chip Camden <sterling AT camdensoftware DOT com>, Nicholas Esborn <nick AT desert DOT net> Approved by: re (kib) MFC after: 10 days
show more ...
|
#
1283e9cd |
| 08-Apr-2011 |
Attilio Rao <attilio@FreeBSD.org> |
Reintroduce the fix already discussed in r216805 (please check its history for a detailed explanation of the problems).
The only difference with the previous fix is in Solution2: CPUBLOCK is no long
Reintroduce the fix already discussed in r216805 (please check its history for a detailed explanation of the problems).
The only difference with the previous fix is in Solution2: CPUBLOCK is no longer set when exiting from callout_reset_*() functions, which avoid the deadlock (leading to r217161). There is no need to CPUBLOCK there because the running-and-migrating assumption is strong enough to avoid problems there. Furthermore add a better !SMP compliancy (leading to shrinked code and structures) and facility macros/functions.
Tested by: gianni, pho, dim MFC after: 3 weeks
show more ...
|
Revision tags: release/7.4.0_cvs, release/8.2.0_cvs, release/7.4.0, release/8.2.0 |
|
#
08e4ac8a |
| 08-Jan-2011 |
Attilio Rao <attilio@FreeBSD.org> |
Revert r216805. That revision is introducing a bug which is more visible than problems it is trying to fix.
As long as my time is very limited in this period I am going to commit back this patch jus
Revert r216805. That revision is introducing a bug which is more visible than problems it is trying to fix.
As long as my time is very limited in this period I am going to commit back this patch just once it is fully fixed.
Reported by: dim, Nicholas Esborn
show more ...
|
#
3d7acbba |
| 29-Dec-2010 |
Attilio Rao <attilio@FreeBSD.org> |
Fix several callout migration races: - Problem1: Hypothesis: thread1 is doing a callout_reset_on(), within his callout handler, willing to implicitly or explicitly migrate the callout. thr
Fix several callout migration races: - Problem1: Hypothesis: thread1 is doing a callout_reset_on(), within his callout handler, willing to implicitly or explicitly migrate the callout. thread2 is draining the callout.
Thesys: * thread1 calls callout_lock() and locks the old callout cpu * thread1 performs the checks in the first path of the callout_reset_on() * thread1 hits this codepiece: /* * If the lock must migrate we have to check the state again as * we can't hold both the new and old locks simultaneously. */ if (c->c_cpu != cpu) { c->c_cpu = cpu; CC_UNLOCK(cc); goto retry; }
which means it will drop the lock and 'retry' * thread2 will callout_lock() and locks the new callout cpu. thread1 spins on the new lock and will not keep going for the moment. * thread2 checks that the callout is not pending (as callout is currently running) and that it is not on cc->cc_curr (because cc now refers to the new callout and the callout is running on the old callout cpu) thus it thinks it is done and returns. * thread1 will now acquire the lock and then adds the callout to the new callout cpu queue
That seems an obvious race as callout_stop() falsely reports the callout stopped or worse, callout_drain() falsely returns while the callout is still in use. - Solution1: Fixing this problem would require, in general, to lock both callout cpus at once while switching the c_cpu field and avoid cyclic deadlocks between callout cpus locks. The concept of CPUBLOCK is then introduced (working more or less like the blocked_lock for thread_lock() function) meaning: "in callout_lock(), spin until the c->c_cpu is not different from CPUBLOCK". That way the "original" callout cpu, referred to the above mentioned code snippet, will remain blocked until the lock handover is over critical path will remain covered.
- Problem2: Having the callout currently executed on a specific callout cpu and contemporary pending on another callout cpu (as it can happen with current code) breaks, at least, the assumption callout_drain() returns just once the callout cannot be referenced anymore. - Solution2: Callout migration is deferred if the current callout is already under execution. The best place to do that is in softclock() and new members are added to the callout cpu structure in order to specify a pending migration is requested. That is necessary because the callout cannot be trusted (not freed) the 100% of times after the execution of the callout handler. CPUBLOCK will prevent, in the "deferred migration" case, that the callout gets freed in this case, stopping any callout_stop() and callout_drain() possible activity until the migration is actually performed.
- Problem3: There is a further race in callout_drain(). In order to avoid a race between sleepqueue lock and callout cpu spinlock, in _callout_stop_safe(), the callout cpu lock is dropped, the sleepqueue lock is acquired and a new callout cpu lookup is performed. Note that the channel used for locking the sleepqueue is obtained from the "current" callout cpu (&cc->cc_waiting). If the callout migrated in the meanwhile, callout_drain() will end up using the wrong wchan for the sleepqueue (the locked one will be the older, while the new one will not really be locked) leading to a lock leak and a race access to sleepqueue. - Solution3: It is enough to check if a migration happened between the operation of acquiring the sleepqueue lock and the new callout cpu lock and eventually unwind all those and try again.
This problems can lead to deathly races on moderate (4-ways) SMP environment, leading to easy panic or deadlocks. The 24-ways of the reporter, could easilly panic, with completely normal workload, almost daily. gianni@ kindly wrote the following prof-of-concept which can panic a FreeBSD machine in less than one hour, in smaller SMP: http://www.freebsd.org/~attilio/callout/test.c
Reported by: Nicholas Esborn <nick at desert dot net>, DesertNet In collabouration with: gianni, pho, Nicholas Esborn Reviewed by: jhb MFC after: 1 week (*)
* Usually, I would aim for a larger MFC timeout, but I really want this in before 8.2-RELEASE, thus re@ accepted a shorter timeout as a special case for this patch
show more ...
|
#
0c21a60c |
| 05-Dec-2010 |
Marcel Moolenaar <marcel@FreeBSD.org> |
svn+ssh://svn.freebsd.org/base/head@216199
|
#
eef8b03c |
| 06-Nov-2010 |
Dimitry Andric <dim@FreeBSD.org> |
Sync: merge r214649 through r214894 from ^/head.
|
#
3350df48 |
| 03-Nov-2010 |
John Baldwin <jhb@FreeBSD.org> |
Remove 'softclock_ih' as it is no longer used.
|
#
b9f2f8c3 |
| 01-Nov-2010 |
Dimitry Andric <dim@FreeBSD.org> |
Sync: merge r214353 through r214648 from ^/head.
|
#
189795fe |
| 31-Oct-2010 |
Alexander Motin <mav@FreeBSD.org> |
Fix callout_tickstofirst() behavior after signed integer ticks overflow. This should fix callout precision drop to 1/4s after 25 days of uptime with HZ = 1000.
Submitted by: Taku YAMAMOTO <taku@tack
Fix callout_tickstofirst() behavior after signed integer ticks overflow. This should fix callout precision drop to 1/4s after 25 days of uptime with HZ = 1000.
Submitted by: Taku YAMAMOTO <taku@tackymt.homeip.net>
show more ...
|
#
6f3544cd |
| 26-Oct-2010 |
Marcel Moolenaar <marcel@FreeBSD.org> |
Merge svn+ssh://svn.freebsd.org/base/head@214309
|
#
9aff0c8f |
| 14-Sep-2010 |
Alexander Motin <mav@FreeBSD.org> |
Fix panic on NULL dereference possible after r212541.
|
#
0e189873 |
| 14-Sep-2010 |
Alexander Motin <mav@FreeBSD.org> |
Make kern_tc.c provide minimum frequency of tc_ticktock() calls, required to handle current timecounter wraps. Make kern_clocksource.c to honor that requirement, scheduling sleeps on first CPU for no
Make kern_tc.c provide minimum frequency of tc_ticktock() calls, required to handle current timecounter wraps. Make kern_clocksource.c to honor that requirement, scheduling sleeps on first CPU for no more then specified period. Allow other CPUs to sleep up to 1/4 second (for any case).
show more ...
|
#
a157e425 |
| 13-Sep-2010 |
Alexander Motin <mav@FreeBSD.org> |
Refactor timer management code with priority to one-shot operation mode. The main goal of this is to generate timer interrupts only when there is some work to do. When CPU is busy interrupts are gene
Refactor timer management code with priority to one-shot operation mode. The main goal of this is to generate timer interrupts only when there is some work to do. When CPU is busy interrupts are generating at full rate of hz + stathz to fullfill scheduler and timekeeping requirements. But when CPU is idle, only minimum set of interrupts (down to 8 interrupts per second per CPU now), needed to handle scheduled callouts is executed. This allows significantly increase idle CPU sleep time, increasing effect of static power-saving technologies. Also it should reduce host CPU load on virtualized systems, when guest system is idle.
There is set of tunables, also available as writable sysctls, allowing to control wanted event timer subsystem behavior: kern.eventtimer.timer - allows to choose event timer hardware to use. On x86 there is up to 4 different kinds of timers. Depending on whether chosen timer is per-CPU, behavior of other options slightly differs. kern.eventtimer.periodic - allows to choose periodic and one-shot operation mode. In periodic mode, current timer hardware taken as the only source of time for time events. This mode is quite alike to previous kernel behavior. One-shot mode instead uses currently selected time counter hardware to schedule all needed events one by one and program timer to generate interrupt exactly in specified time. Default value depends of chosen timer capabilities, but one-shot mode is preferred, until other is forced by user or hardware. kern.eventtimer.singlemul - in periodic mode specifies how much times higher timer frequency should be, to not strictly alias hardclock() and statclock() events. Default values are 2 and 4, but could be reduced to 1 if extra interrupts are unwanted. kern.eventtimer.idletick - makes each CPU to receive every timer interrupt independently of whether they busy or not. By default this options is disabled. If chosen timer is per-CPU and runs in periodic mode, this option has no effect - all interrupts are generating.
As soon as this patch modifies cpu_idle() on some platforms, I have also refactored one on x86. Now it makes use of MONITOR/MWAIT instrunctions (if supported) under high sleep/wakeup rate, as fast alternative to other methods. It allows SMP scheduler to wake up sleeping CPUs much faster without using IPI, significantly increasing performance on some highly task-switching loads.
Tested by: many (on i386, amd64, sparc64 and powerc) H/W donated by: Gheorghe Ardelean Sponsored by: iXsystems, Inc.
show more ...
|
#
79856499 |
| 22-Aug-2010 |
Rui Paulo <rpaulo@FreeBSD.org> |
Add an extra comment to the SDT probes definition. This allows us to get use '-' in probe names, matching the probe names in Solaris.[1]
Add userland SDT probes definitions to sys/sdt.h.
Sponsored
Add an extra comment to the SDT probes definition. This allows us to get use '-' in probe names, matching the probe names in Solaris.[1]
Add userland SDT probes definitions to sys/sdt.h.
Sponsored by: The FreeBSD Foundation Discussed with: rwaston [1]
show more ...
|
Revision tags: release/8.1.0_cvs, release/8.1.0 |
|
#
95bf6530 |
| 12-Jun-2010 |
Marcel Moolenaar <marcel@FreeBSD.org> |
Merge svn+ssh://svn.freebsd.org/base/head@209086
|
#
3aa6d94e |
| 11-Jun-2010 |
John Baldwin <jhb@FreeBSD.org> |
Update several places that iterate over CPUs to use CPU_FOREACH().
|
Revision tags: release/7.3.0_cvs, release/7.3.0 |
|
#
f078d861 |
| 07-Mar-2010 |
Luigi Rizzo <luigi@FreeBSD.org> |
MFC r197137 and r200510, which fixes a problem in 8.0 with callouts firing one tick too late. See the logs for the original patch for details. RELENG_7 is not affected by the problem.
|
#
1a0fda2b |
| 04-Mar-2010 |
Dag-Erling Smørgrav <des@FreeBSD.org> |
IFH@204581
|
#
9199c09a |
| 06-Jan-2010 |
Warner Losh <imp@FreeBSD.org> |
Merge from head at r201628.
# This hasn't been tested, and there are at least three bad commits # that need to be backed out before the branch will be stable again.
|
#
20c510f8 |
| 14-Dec-2009 |
Luigi Rizzo <luigi@FreeBSD.org> |
Properly fix callout handling by putting all the per-cpu info in struct callout_cpu. From the comment in the file:
+ * There is one struct callout_cpu per cpu, holding all relevant + * state for the
Properly fix callout handling by putting all the per-cpu info in struct callout_cpu. From the comment in the file:
+ * There is one struct callout_cpu per cpu, holding all relevant + * state for the callout processing thread on the individual CPU. + * In particular: + * cc_ticks is incremented once per tick in callout_cpu(). + * It tracks the global 'ticks' but in a way that the individual + * threads should not worry about races in the order in which + * hardclock() and hardclock_cpu() run on the various CPUs. + * cc_softclock is advanced in callout_cpu() to point to the + * first entry in cc_callwheel that may need handling. In turn, + * a softclock() is scheduled so it can serve the various entries i + * such that cc_softclock <= i <= cc_ticks .
Together with a smaller patch committed in september, this fixes a bug that affects 8.0 with apps that rely on callouts to fire exactly in the number of ticks specified (qemu among them). Right now, callouts in 8.0 fire one tick late.
This was discussed in september with JeffR and jhb
MFC after: 3 days
show more ...
|
Revision tags: release/8.0.0_cvs, release/8.0.0 |
|
#
1ee774f6 |
| 02-Oct-2009 |
Oleksandr Tymoshenko <gonzo@FreeBSD.org> |
- MFC
|
#
10b3b545 |
| 17-Sep-2009 |
Dag-Erling Smørgrav <des@FreeBSD.org> |
Merge from head
|
#
7d4b968b |
| 17-Sep-2009 |
Dag-Erling Smørgrav <des@FreeBSD.org> |
Merge from head up to r188941 (last revision before the USB stack switch)
|
#
446e8617 |
| 12-Sep-2009 |
Luigi Rizzo <luigi@FreeBSD.org> |
Make sure callouts are not processed one tick late. The problem was introduced in SVN 180608/ rev 1.114 and affects all users of callout_reset() (including select, usleep, setitimer). A better fix pr
Make sure callouts are not processed one tick late. The problem was introduced in SVN 180608/ rev 1.114 and affects all users of callout_reset() (including select, usleep, setitimer). A better fix probably involves replicating 'ticks' in the struct callout_cpu; this commit is just a temporary thing so that we can MFC it after a suitable test time and RE approval.
MFC after: 3 days
show more ...
|
Revision tags: release/7.2.0_cvs, release/7.2.0 |
|
#
1829d5da |
| 12-Mar-2009 |
Warner Losh <imp@FreeBSD.org> |
Update the projects tree to a newer FreeBSD current.
|