From owner-svn-src-head@FreeBSD.ORG Tue Jan 20 22:43:27 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 0E889DAD; Tue, 20 Jan 2015 22:43:27 +0000 (UTC) Received: from mail-yk0-x22d.google.com (mail-yk0-x22d.google.com [IPv6:2607:f8b0:4002:c07::22d]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id BFC3B918; Tue, 20 Jan 2015 22:43:26 +0000 (UTC) Received: by mail-yk0-f173.google.com with SMTP id 142so2899349ykq.4; Tue, 20 Jan 2015 14:43:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; bh=w1mGmvnti1vdI4eGWpqluVvcfh+oid55ZzhC/D8s3yM=; b=AIciQCv2rjFhO8Xs0lOwSuOz7TBOyB0JNQ2zLv590yp+0pfQyb/1TBSmWtESs4x1B8 XuN9+mmYc1pRbY/nAfovGbA8Qp7aP+5kFxUWxm/HDM2vWUdhZZ0dxESqLNyYhf4xKt/t fO5IOB55ZmcuZKoh+LZR9YaUp9SRjFYaa2iWjx68jSWsMcwb3HKp5OVZDmnTYmsVMcNe RYi6clQ0fCI9k0qL9perLruC/OTo5Pswl3K+x8nwUPKeD08nkBrVLNeWUPRcFlMghLIA a24W6/izD2gwoACEr/E138fLCXWVm1EOx5o3STpgChyqq7IYsCyUck/2h+ymy04xHykp 0tsg== MIME-Version: 1.0 X-Received: by 10.236.40.116 with SMTP id e80mr21942262yhb.186.1421793805896; Tue, 20 Jan 2015 14:43:25 -0800 (PST) Sender: kmacybsd@gmail.com Received: by 10.170.70.132 with HTTP; Tue, 20 Jan 2015 14:43:25 -0800 (PST) In-Reply-To: <201501151532.t0FFWV2Y037455@svn.freebsd.org> References: <201501151532.t0FFWV2Y037455@svn.freebsd.org> Date: Tue, 20 Jan 2015 14:43:25 -0800 X-Google-Sender-Auth: nK1zISttqpPlp6lZRXNBMFraSnk Message-ID: Subject: Re: svn commit: r277213 - in head: share/man/man9 sys/kern sys/ofed/include/linux sys/sys From: "K. Macy" To: Hans Petter Selasky Content-Type: text/plain; charset=UTF-8 Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Jan 2015 22:43:27 -0000 Please back this out now. It was a substantial interface change without review. This should not be up for debate. I hope the others have the fortitude to insist upon this. -K On Thu, Jan 15, 2015 at 7:32 AM, Hans Petter Selasky wrote: > Author: hselasky > Date: Thu Jan 15 15:32:30 2015 > New Revision: 277213 > URL: https://svnweb.freebsd.org/changeset/base/277213 > > Log: > Major callout subsystem cleanup and rewrite: > - Close a migration race where callout_reset() failed to set the > CALLOUT_ACTIVE flag. > - Callout callback functions are now allowed to be protected by > spinlocks. > - Switching the callout CPU number cannot always be done on a > per-callout basis. See the updated timeout(9) manual page for more > information. > - The timeout(9) manual page has been updated to reflect how all the > functions inside the callout API are working. The manual page has > been made function oriented to make it easier to deduce how each of > the functions making up the callout API are working without having > to first read the whole manual page. Group all functions into a > handful of sections which should give a quick top-level overview > when the different functions should be used. > - The CALLOUT_SHAREDLOCK flag and its functionality has been removed > to reduce the complexity in the callout code and to avoid problems > about atomically stopping callouts via callout_stop(). If someone > needs it, it can be re-added. From my quick grep there are no > CALLOUT_SHAREDLOCK clients in the kernel. > - A new callout API function named "callout_drain_async()" has been > added. See the updated timeout(9) manual page for a complete > description. > - Update the callout clients in the "kern/" folder to use the callout > API properly, like cv_timedwait(). Previously there was some custom > sleepqueue code in the callout subsystem, which has been removed, > because we now allow callouts to be protected by spinlocks. This > allows us to tear down the callout like done with regular mutexes, > and a "td_slpmutex" has been added to "struct thread" to atomically > teardown the "td_slpcallout". Further the "TDF_TIMOFAIL" and > "SWT_SLEEPQTIMO" states can now be completely removed. Currently > they are marked as available and will be cleaned up in a follow up > commit. > - Bump the __FreeBSD_version to indicate kernel modules need > recompilation. > - There has been several reports that this patch "seems to squash a > serious bug leading to a callout timeout and panic". > > Kernel build testing: all architectures were built > MFC after: 2 weeks > Differential Revision: https://reviews.freebsd.org/D1438 > Sponsored by: Mellanox Technologies > Reviewed by: jhb, adrian, sbruno and emaste > > Modified: > head/share/man/man9/Makefile > head/share/man/man9/timeout.9 > head/sys/kern/init_main.c > head/sys/kern/kern_condvar.c > head/sys/kern/kern_lock.c > head/sys/kern/kern_switch.c > head/sys/kern/kern_synch.c > head/sys/kern/kern_thread.c > head/sys/kern/kern_timeout.c > head/sys/kern/subr_sleepqueue.c > head/sys/ofed/include/linux/completion.h > head/sys/sys/_callout.h > head/sys/sys/callout.h > head/sys/sys/param.h > head/sys/sys/proc.h > > Modified: head/share/man/man9/Makefile > ============================================================================== > --- head/share/man/man9/Makefile Thu Jan 15 14:47:48 2015 (r277212) > +++ head/share/man/man9/Makefile Thu Jan 15 15:32:30 2015 (r277213) > @@ -1570,6 +1570,7 @@ MLINKS+=timeout.9 callout.9 \ > timeout.9 callout_active.9 \ > timeout.9 callout_deactivate.9 \ > timeout.9 callout_drain.9 \ > + timeout.9 callout_drain_async.9 \ > timeout.9 callout_handle_init.9 \ > timeout.9 callout_init.9 \ > timeout.9 callout_init_mtx.9 \ > > Modified: head/share/man/man9/timeout.9 > ============================================================================== > --- head/share/man/man9/timeout.9 Thu Jan 15 14:47:48 2015 (r277212) > +++ head/share/man/man9/timeout.9 Thu Jan 15 15:32:30 2015 (r277213) > @@ -29,13 +29,14 @@ > .\" > .\" $FreeBSD$ > .\" > -.Dd October 8, 2014 > +.Dd January 14, 2015 > .Dt TIMEOUT 9 > .Os > .Sh NAME > .Nm callout_active , > .Nm callout_deactivate , > .Nm callout_drain , > +.Nm callout_drain_async , > .Nm callout_handle_init , > .Nm callout_init , > .Nm callout_init_mtx , > @@ -63,279 +64,232 @@ > .In sys/systm.h > .Bd -literal > typedef void timeout_t (void *); > +typedef void callout_func_t (void *); > .Ed > -.Ft int > -.Fn callout_active "struct callout *c" > -.Ft void > -.Fn callout_deactivate "struct callout *c" > -.Ft int > -.Fn callout_drain "struct callout *c" > -.Ft void > -.Fn callout_handle_init "struct callout_handle *handle" > -.Bd -literal > -struct callout_handle handle = CALLOUT_HANDLE_INITIALIZER(&handle); > -.Ed > -.Ft void > -.Fn callout_init "struct callout *c" "int mpsafe" > -.Ft void > -.Fn callout_init_mtx "struct callout *c" "struct mtx *mtx" "int flags" > -.Ft void > -.Fn callout_init_rm "struct callout *c" "struct rmlock *rm" "int flags" > -.Ft void > -.Fn callout_init_rw "struct callout *c" "struct rwlock *rw" "int flags" > -.Ft int > -.Fn callout_pending "struct callout *c" > -.Ft int > -.Fn callout_reset "struct callout *c" "int ticks" "timeout_t *func" "void *arg" > -.Ft int > -.Fn callout_reset_curcpu "struct callout *c" "int ticks" "timeout_t *func" \ > -"void *arg" > -.Ft int > -.Fn callout_reset_on "struct callout *c" "int ticks" "timeout_t *func" \ > -"void *arg" "int cpu" > -.Ft int > -.Fn callout_reset_sbt "struct callout *c" "sbintime_t sbt" \ > -"sbintime_t pr" "timeout_t *func" "void *arg" "int flags" > -.Ft int > -.Fn callout_reset_sbt_curcpu "struct callout *c" "sbintime_t sbt" \ > -"sbintime_t pr" "timeout_t *func" "void *arg" "int flags" > -.Ft int > -.Fn callout_reset_sbt_on "struct callout *c" "sbintime_t sbt" \ > -"sbintime_t pr" "timeout_t *func" "void *arg" "int cpu" "int flags" > -.Ft int > -.Fn callout_schedule "struct callout *c" "int ticks" > -.Ft int > -.Fn callout_schedule_curcpu "struct callout *c" "int ticks" > -.Ft int > -.Fn callout_schedule_on "struct callout *c" "int ticks" "int cpu" > -.Ft int > -.Fn callout_schedule_sbt "struct callout *c" "sbintime_t sbt" \ > -"sbintime_t pr" "int flags" > -.Ft int > -.Fn callout_schedule_sbt_curcpu "struct callout *c" "sbintime_t sbt" \ > -"sbintime_t pr" "int flags" > -.Ft int > -.Fn callout_schedule_sbt_on "struct callout *c" "sbintime_t sbt" \ > -"sbintime_t pr" "int cpu" "int flags" > -.Ft int > -.Fn callout_stop "struct callout *c" > -.Ft struct callout_handle > -.Fn timeout "timeout_t *func" "void *arg" "int ticks" > -.Ft void > -.Fn untimeout "timeout_t *func" "void *arg" "struct callout_handle handle" > .Sh DESCRIPTION > The > .Nm callout > API is used to schedule a call to an arbitrary function at a specific > -time in the future. > -Consumers of this API are required to allocate a callout structure > +time in the future in a single-shot fashion. > +Consumers of this API are required to allocate a > .Pq struct callout > -for each pending function invocation. > -This structure stores state about the pending function invocation including > -the function to be called and the time at which the function should be invoked. > -Pending function calls can be cancelled or rescheduled to a different time. > -In addition, > -a callout structure may be reused to schedule a new function call after a > -scheduled call is completed. > -.Pp > -Callouts only provide a single-shot mode. > -If a consumer requires a periodic timer, > -it must explicitly reschedule each function call. > -This is normally done by rescheduling the subsequent call within the called > -function. > +structure for each pending function invocation. > +The > +.Pq struct callout > +structure stores the full state about any pending function call and > +should be drained by a call to > +.Fn callout_drain > +or > +.Fn callout_drain_async > +before freeing. > +.Sh INITIALISATION > +.Ft void > +.Fn callout_handle_init "struct callout_handle *handle" > +This function is deprecated and is used to prepare a > +.Pq struct callout_handle > +structure before it can be used the first time. > +If this function is called on a pending timeout, the pending timeout > +cannot be cancelled and the > +.Fn untimeout > +function will return as if there was no timeout pending. > .Pp > -Callout functions must not sleep. > -They may not acquire sleepable locks, > -wait on condition variables, > -perform blocking allocation requests, > -or invoke any other action that might sleep. > +.Fn CALLOUT_HANDLE_INITIALIZER "&handle" > +This macro is deprecated and can be used instead of > +.Fn callout_handle_init > +to assign the default state to the > +.Pq struct callout_handle > +structure when declaring static timeouts. > .Pp > -Each callout structure must be initialized by > -.Fn callout_init , > -.Fn callout_init_mtx , > -.Fn callout_init_rm , > -or > -.Fn callout_init_rw > -before it is passed to any of the other callout functions. > -The > -.Fn callout_init > -function initializes a callout structure in > -.Fa c > -that is not associated with a specific lock. > +.Ft void > +.Fn callout_init "struct callout *c" "int mpsafe" > +This function prepares a > +.Pq struct callout > +structure before it can be used. > +This function should not be used when the callout is pending a timeout. > If the > .Fa mpsafe > -argument is zero, > -the callout structure is not considered to be > -.Dq multi-processor safe ; > -and the Giant lock will be acquired before calling the callout function > -and released when the callout function returns. > +argument is non-zero, the callback function will be running unlocked. > +Else the Giant mutex will be locked before calling the callback function. > .Pp > +.Ft void > +.Fn callout_init_mtx "struct callout *c" "struct mtx *mtx" "int flags" > +This function prepares a > +.Pq struct callout > +structure before it can be used. > +This function should not be used when the callout is pending a timeout. > The > -.Fn callout_init_mtx , > -.Fn callout_init_rm , > -and > -.Fn callout_init_rw > -functions initialize a callout structure in > -.Fa c > -that is associated with a specific lock. > -The lock is specified by the > -.Fa mtx , > -.Fa rm , > -or > -.Fa rw > -parameter. > -The associated lock must be held while stopping or rescheduling the > -callout. > -The callout subsystem acquires the associated lock before calling the > -callout function and releases it after the function returns. > -If the callout was cancelled while the callout subsystem waited for the > -associated lock, > -the callout function is not called, > -and the associated lock is released. > -This ensures that stopping or rescheduling the callout will abort any > -previously scheduled invocation. > -.Pp > -Only regular mutexes may be used with > -.Fn callout_init_mtx ; > -spin mutexes are not supported. > -A sleepable read-mostly lock > -.Po > -one initialized with the > -.Dv RM_SLEEPABLE > -flag > -.Pc > -may not be used with > -.Fn callout_init_rm . > -Similarly, other sleepable lock types such as > -.Xr sx 9 > -and > -.Xr lockmgr 9 > -cannot be used with callouts because sleeping is not permitted in > -the callout subsystem. > -.Pp > -These > +.Fa mtx > +argument should be non-zero and should specify a pointer to a valid > +spinlock type of mutex or a valid regular non-sleepable mutex which > +the callback subsystem should lock before calling the callback > +function. > +Valid > .Fa flags > -may be specified for > -.Fn callout_init_mtx , > -.Fn callout_init_rm , > -or > -.Fn callout_init_rw : > +are: > .Bl -tag -width ".Dv CALLOUT_RETURNUNLOCKED" > .It Dv CALLOUT_RETURNUNLOCKED > -The callout function will release the associated lock itself, > -so the callout subsystem should not attempt to unlock it > -after the callout function returns. > -.It Dv CALLOUT_SHAREDLOCK > -The lock is only acquired in read mode when running the callout handler. > -This flag is ignored by > -.Fn callout_init_mtx . > +It is assumed that the callout function has released the specified > +mutex before returning. > +Else the callout subsystem will release the specified mutex after the > +callout function has returned. > .El > .Pp > -The function > -.Fn callout_stop > -cancels a callout > -.Fa c > -if it is currently pending. > -If the callout is pending, then > -.Fn callout_stop > -returns a non-zero value. > -If the callout is not set, > -has already been serviced, > -or is currently being serviced, > -then zero will be returned. > -If the callout has an associated lock, > -then that lock must be held when this function is called. > -.Pp > -The function > -.Fn callout_drain > -is identical to > -.Fn callout_stop > -except that it will wait for the callout > -.Fa c > -to complete if it is already in progress. > -This function MUST NOT be called while holding any > -locks on which the callout might block, or deadlock will result. > -Note that if the callout subsystem has already begun processing this > -callout, then the callout function may be invoked before > -.Fn callout_drain > -returns. > -However, the callout subsystem does guarantee that the callout will be > -fully stopped before > -.Fn callout_drain > -returns. > -.Pp > -The > -.Fn callout_reset > -and > -.Fn callout_schedule > -function families schedule a future function invocation for callout > -.Fa c . > -If > -.Fa c > -already has a pending callout, > -it is cancelled before the new invocation is scheduled. > -These functions return a non-zero value if a pending callout was cancelled > -and zero if there was no pending callout. > -If the callout has an associated lock, > -then that lock must be held when any of these functions are called. > +.Ft void > +.Fn callout_init_rm "struct callout *c" "struct rmlock *rm" "int flags" > +This function is the same like the > +.Fn callout_init_mtx > +function except it accepts a read-mostly type of lock. > +The read-mostly lock must not be initialised with the > +.Dv RM_SLEEPABLE > +flag. > .Pp > -The time at which the callout function will be invoked is determined by > -either the > -.Fa ticks > -argument or the > -.Fa sbt , > -.Fa pr , > -and > -.Fa flags > -arguments. > -When > -.Fa ticks > -is used, > -the callout is scheduled to execute after > +.Ft void > +.Fn callout_init_rw "struct callout *c" "struct rwlock *rw" "int flags" > +This function is the same like the > +.Fn callout_init_mtx > +function except it accepts a reader-writer type of lock. > +.Sh SCHEDULING CALLOUTS > +.Ft struct callout_handle > +.Fn timeout "timeout_t *func" "void *arg" "int ticks" > +This function is deprecated and schedules a call to the function given by the argument > +.Fa func > +to take place after > .Fa ticks Ns No /hz > seconds. > Non-positive values of > .Fa ticks > are silently converted to the value > .Sq 1 . > -.Pp > The > -.Fa sbt , > -.Fa pr , > -and > -.Fa flags > -arguments provide more control over the scheduled time including > -support for higher resolution times, > -specifying the precision of the scheduled time, > -and setting an absolute deadline instead of a relative timeout. > -The callout is scheduled to execute in a time window which begins at > -the time specified in > +.Fa func > +argument should be a valid pointer to a function that takes a single > +.Fa void * > +argument. > +Upon invocation, the > +.Fa func > +function will receive > +.Fa arg > +as its only argument. > +The Giant lock is locked when the > +.Fa arg > +function is invoked and should not be unlocked by this function. > +The returned value from > +.Fn timeout > +is a > +.Ft struct callout_handle > +structure which can be used in conjunction with the > +.Fn untimeout > +function to request that a scheduled timeout be cancelled. > +As handles are recycled by the system, it is possible, although unlikely, > +that a handle from one invocation of > +.Fn timeout > +may match the handle of another invocation of > +.Fn timeout > +if both calls used the same function pointer and argument, and the first > +timeout is expired or canceled before the second call. > +Please ensure that the function and argument pointers are unique when using this function. > +.Pp > +.Ft int > +.Fn callout_reset "struct callout *c" "int ticks" "callout_func_t *func" "void *arg" > +This function is used to schedule or re-schedule a callout. > +This function at first stops the callout given by the > +.Fa c > +argument, if any. > +Then it will start the callout given by the > +.Fa c > +argument. > +The relative time until the timeout callback happens is given by the > +.Fa ticks > +argument. > +The number of ticks in a second is defined by > +.Dv hz > +and can vary from system to system. > +This function returns a non-zero value if the given callout was pending and > +the callback function was prevented from being called. > +Else a value of zero is returned. > +If a lock is associated with the callout given by the > +.Fa c > +argument and it is exclusivly locked when this function is called this > +function will always ensure that previous callback function, if any, > +is never reached. > +In other words the callout will be atomically restarted. > +Else there is no such guarantee. > +The callback function is given by the > +.Fa func > +argument and its function argument is given by the > +.Fa arg > +argument. > +.Pp > +.Ft int > +.Fn callout_reset_curcpu "struct callout *c" "int ticks" "callout_func_t *func" \ > +"void *arg" > +This function works the same like the > +.Fn callout_reset > +function except the callback function given by the > +.Fa func > +argument will be executed on the same CPU which called this function. > +A change in the CPU selection can happen if the callout has a lock > +associated with it and is locked when this function is called. > +A change in the CPU selection cannot happen if this function is > +re-scheduled inside a callout function. > +Else the callback function given by the > +.Fa func > +argument will be executed on the same CPU like previously done. > +.Pp > +.Ft int > +.Fn callout_reset_on "struct callout *c" "int ticks" "callout_func_t *func" \ > +"void *arg" "int cpu" > +This function works the same like the > +.Fn callout_reset > +function except the callback function given by the > +.Fa func > +argument will be executed on the CPU given by the > +.Fa cpu > +argument. > +A change in the CPU selection can happen if the callout has a lock > +associated with it and is locked when this function is called. > +A change in the CPU selection cannot happen if this function is > +re-scheduled inside a callout function. > +Else the callback function given by the > +.Fa func > +argument will be executed on the same CPU like previously done. > +.Pp > +.Ft int > +.Fn callout_reset_sbt "struct callout *c" "sbintime_t sbt" \ > +"sbintime_t pr" "callout_func_t *func" "void *arg" "int flags" > +This function works the same like the > +.Fn callout_reset > +function except the relative or absolute time after which the timeout > +callback should happen is given by the > .Fa sbt > -and extends for the amount of time specified in > -.Fa pr . > -If > +argument and extends for the amount of time specified in the > +.Fa pr > +argument. > +This function is used when you need high precision timeouts. > +If the > .Fa sbt > -specifies a time in the past, > +argument specifies a time in the past, > the window is adjusted to start at the current time. > A non-zero value for > .Fa pr > allows the callout subsystem to coalesce callouts scheduled close to each > other into fewer timer interrupts, > reducing processing overhead and power consumption. > -These > +The > .Fa flags > -may be specified to adjust the interpretation of > +argument may be non-zero to adjust the interpretation of the > .Fa sbt > -and > -.Fa pr : > +and the > +.Fa pr > +arguments: > .Bl -tag -width ".Dv C_DIRECT_EXEC" > .It Dv C_ABSOLUTE > Handle the > .Fa sbt > argument as an absolute time since boot. > -By default, > +By default, the > .Fa sbt > -is treated as a relative amount of time, > +argument is treated like a relative amount of time, > similar to > .Fa ticks . > .It Dv C_DIRECT_EXEC > @@ -347,7 +301,7 @@ Callout functions run in this context ma > and should be as small as possible because they run with absolute priority. > .It Fn C_PREL > Specifies relative event time precision as binary logarithm of time interval > -divided by acceptable time deviation: 1 -- 1/2, 2 -- 1/4, etc. > +divided by acceptable time deviation: 1 -- 1/2, 2 -- 1/4 and so on. > Note that the larger of > .Fa pr > or this value is used as the length of the time window. > @@ -360,65 +314,215 @@ Align the timeouts to > calls if possible. > .El > .Pp > -The > -.Fn callout_reset > -functions accept a > +.Ft int > +.Fn callout_reset_sbt_curcpu "struct callout *c" "sbintime_t sbt" \ > +"sbintime_t pr" "callout_func_t *func" "void *arg" "int flags" > +This function works the same like the > +.Fn callout_reset_sbt > +function except the callback function given by the > .Fa func > -argument which identifies the function to be called when the time expires. > -It must be a pointer to a function that takes a single > -.Fa void * > +argument will be executed on the same CPU which called this function. > +A change in the CPU selection can happen if the callout has a lock > +associated with it and is locked when this function is called. > +A change in the CPU selection cannot happen if this function is > +re-scheduled inside a callout function. > +Else the callback function given by the > +.Fa func > +argument will be executed on the same CPU like previously done. > +.Pp > +.Ft int > +.Fn callout_reset_sbt_on "struct callout *c" "sbintime_t sbt" \ > +"sbintime_t pr" "callout_func_t *func" "void *arg" "int cpu" "int flags" > +This function works the same like the > +.Fn callout_reset_sbt > +function except the callback function given by the > +.Fa func > +argument will be executed on the CPU given by the > +.Fa cpu > argument. > -Upon invocation, > +A change in the CPU selection can happen if the callout has a lock > +associated with it and is locked when this function is called. > +A change in the CPU selection cannot happen if this function is > +re-scheduled inside a callout function. > +Else the callback function given by the > .Fa func > -will receive > -.Fa arg > -as its only argument. > -The > -.Fn callout_schedule > -functions reuse the > +argument will be executed on the same CPU like previously done. > +.Pp > +.Ft int > +.Fn callout_schedule "struct callout *c" "int ticks" > +This function works the same like the > +.Fn callout_reset > +function except it re-uses the callback function and the callback argument > +already stored in the > +.Pq struct callout > +structure. > +.Pp > +.Ft int > +.Fn callout_schedule_curcpu "struct callout *c" "int ticks" > +This function works the same like the > +.Fn callout_reset_curcpu > +function except it re-uses the callback function and the callback argument > +already stored in the > +.Pq struct callout > +structure. > +.Pp > +.Ft int > +.Fn callout_schedule_on "struct callout *c" "int ticks" "int cpu" > +This function works the same like the > +.Fn callout_reset_on > +function except it re-uses the callback function and the callback argument > +already stored in the > +.Pq struct callout > +structure. > +.Pp > +.Ft int > +.Fn callout_schedule_sbt "struct callout *c" "sbintime_t sbt" \ > +"sbintime_t pr" "int flags" > +This function works the same like the > +.Fn callout_reset_sbt > +function except it re-uses the callback function and the callback argument > +already stored in the > +.Pq struct callout > +structure. > +.Pp > +.Ft int > +.Fn callout_schedule_sbt_curcpu "struct callout *c" "sbintime_t sbt" \ > +"sbintime_t pr" "int flags" > +This function works the same like the > +.Fn callout_reset_sbt_curcpu > +function except it re-uses the callback function and the callback argument > +already stored in the > +.Pq struct callout > +structure. > +.Pp > +.Ft int > +.Fn callout_schedule_sbt_on "struct callout *c" "sbintime_t sbt" \ > +"sbintime_t pr" "int cpu" "int flags" > +This function works the same like the > +.Fn callout_reset_sbt_on > +function except it re-uses the callback function and the callback argument > +already stored in the > +.Pq struct callout > +structure. > +.Sh CHECKING THE STATE OF CALLOUTS > +.Ft int > +.Fn callout_pending "struct callout *c" > +This function returns non-zero if the callout pointed to by the > +.Fa c > +argument is pending for callback. > +Else this function returns zero. > +This function returns zero when inside the callout function if the > +callout is not re-scheduled. > +.Pp > +.Ft int > +.Fn callout_active "struct callout *c" > +This function is deprecated and returns non-zero if the callout > +pointed to by the > +.Fa c > +argument was scheduled in the past. > +Else this function returns zero. > +This function also returns zero after the > +.Fn callout_deactivate > +or the > +.Fn callout_stop > +or the > +.Fn callout_drain > +or the > +.Fn callout_drain_async > +function is called on the same callout as given by the > +.Fa c > +argument. > +.Pp > +.Ft void > +.Fn callout_deactivate "struct callout *c" > +This function is deprecated and ensures that subsequent calls to the > +.Fn callout_activate > +function returns zero until the callout is scheduled again. > +.Sh STOPPING CALLOUTS > +.Ft void > +.Fn untimeout "timeout_t *func" "void *arg" "struct callout_handle handle" > +This function is deprecated and cancels the timeout associated with the > +.Fa handle > +argument using the function pointed to by the > .Fa func > -and > +argument and having the > .Fa arg > -arguments from the previous callout. > -Note that one of the > -.Fn callout_reset > -functions must always be called to initialize > +arguments to validate the handle. > +If the handle does not correspond to a timeout with > +the function > .Fa func > -and > +taking the argument > .Fa arg > -before one of the > -.Fn callout_schedule > -functions can be used. > +no action is taken. The > +.Fa handle > +must be initialised by a previous call to > +.Fn timeout , > +.Fn callout_handle_init > +or assigned the value of > +.Fn CALLOUT_HANDLE_INITIALIZER "&handle" > +before being passed to > +.Fn untimeout . > +The behavior of calling > +.Fn untimeout > +with an uninitialised handle > +is undefined. > .Pp > -The callout subsystem provides a softclock thread for each CPU in the system. > -Callouts are assigned to a single CPU and are executed by the softclock thread > -for that CPU. > -Initially, > -callouts are assigned to CPU 0. > -The > -.Fn callout_reset_on , > -.Fn callout_reset_sbt_on , > -.Fn callout_schedule_on > -and > -.Fn callout_schedule_sbt_on > -functions assign the callout to CPU > -.Fa cpu . > -The > -.Fn callout_reset_curcpu , > -.Fn callout_reset_sbt_curpu , > -.Fn callout_schedule_curcpu > -and > -.Fn callout_schedule_sbt_curcpu > -functions assign the callout to the current CPU. > -The > -.Fn callout_reset , > -.Fn callout_reset_sbt , > -.Fn callout_schedule > -and > -.Fn callout_schedule_sbt > -functions schedule the callout to execute in the softclock thread of the CPU > -to which it is currently assigned. > +.Ft int > +.Fn callout_stop "struct callout *c" > +This function is used to stop a timeout function invocation associated with the callout pointed to by the > +.Fa c > +argument, in a non-blocking fashion. > +This function can be called multiple times in a row with no side effects, even if the callout is already stopped. This function however should not be called before the callout has been initialised. > +This function returns a non-zero value if the given callout was pending and > +the callback function was prevented from being called. > +Else a value of zero is returned. > +If a lock is associated with the callout given by the > +.Fa c > +argument and it is exclusivly locked when this function is called, the > +.Fn callout_stop > +function will always ensure that the callback function is never reached. > +In other words the callout will be atomically stopped. > +Else there is no such guarantee. > +.Sh DRAINING CALLOUTS > +.Ft int > +.Fn callout_drain "struct callout *c" > +This function works the same like the > +.Fn callout_stop > +function except it ensures that all callback functions have returned and there are no more references to the callout pointed to by the > +.Fa c > +argument inside the callout subsystem before it returns. > +Also this function ensures that the lock, if any, associated with the > +callout is no longer being used. > +When this function returns, it is safe to free the callout structure pointed to by the > +.Fa c > +argument. > .Pp > +.Ft int > +.Fn callout_drain_async "struct callout *c" "callout_func_t *fn" "void *arg" > +This function is non-blocking and works the same like the > +.Fn callout_stop > +function except if it returns non-zero it means the callback function pointed to by the > +.Fa fn > +argument will be called back with the > +.Fa arg > +argument when all references to the callout pointed to by the > +.Fa c > +argument are gone. > +If this function returns zero, it is safe to free the callout structure pointed to by the > +.Fa c > +argument right away. > +.Sh CALLOUT FUNCTION RESTRICTIONS > +Callout functions must not sleep. > +They may not acquire sleepable locks, wait on condition variables, > +perform blocking allocation requests, or invoke any other action that > +might sleep. > +.Sh CALLOUT SUBSYSTEM INTERNALS > +The callout subsystem has its own set of spinlocks to protect its internal state. > +The callout subsystem provides a softclock thread for each CPU in the > +system. > +Callouts are assigned to a single CPU and are executed by the > +softclock thread for that CPU. > +Initially, callouts are assigned to CPU 0. > Softclock threads are not pinned to their respective CPUs by default. > The softclock thread for CPU 0 can be pinned to CPU 0 by setting the > .Va kern.pin_default_swi > @@ -427,50 +531,7 @@ Softclock threads for CPUs other than ze > respective CPUs by setting the > .Va kern.pin_pcpu_swi > loader tunable to a non-zero value. > -.Pp > -The macros > -.Fn callout_pending , > -.Fn callout_active > -and > -.Fn callout_deactivate > -provide access to the current state of the callout. > -The > -.Fn callout_pending > -macro checks whether a callout is > -.Em pending ; > -a callout is considered > -.Em pending > -when a timeout has been set but the time has not yet arrived. > -Note that once the timeout time arrives and the callout subsystem > -starts to process this callout, > -.Fn callout_pending > -will return > -.Dv FALSE > -even though the callout function may not have finished > -.Pq or even begun > -executing. > -The > -.Fn callout_active > -macro checks whether a callout is marked as > -.Em active , > -and the > -.Fn callout_deactivate > -macro clears the callout's > -.Em active > -flag. > -The callout subsystem marks a callout as > -.Em active > -when a timeout is set and it clears the > -.Em active > -flag in > -.Fn callout_stop > -and > -.Fn callout_drain , > -but it > -.Em does not > -clear it when a callout expires normally via the execution of the > -callout function. > -.Ss "Avoiding Race Conditions" > +.Sh "AVOIDING RACE CONDITIONS" > The callout subsystem invokes callout functions from its own thread > context. > Without some kind of synchronization, > @@ -487,7 +548,7 @@ synchronization concerns. > The first approach is preferred as it is the simplest: > .Bl -enum -offset indent > .It > -Callouts can be associated with a specific lock when they are initialized > +Callouts can be associated with a specific lock when they are initialised > by > .Fn callout_init_mtx , > .Fn callout_init_rm , > @@ -508,7 +569,7 @@ or > .Fn callout_schedule > functions to provide this safety. > .Pp > -A callout initialized via > +A callout initialised via > .Fn callout_init > with > .Fa mpsafe > @@ -531,9 +592,8 @@ function families > .Pc > indicates whether or not the callout was removed. > If it is known that the callout was set and the callout function has > -not yet executed, then a return value of > -.Dv FALSE > -indicates that the callout function is about to be called. > +not yet executed, then a return value of zero indicates that the > +callout function is about to be called. > For example: > .Bd -literal -offset indent > if (sc->sc_flags & SCFLG_CALLOUT_RUNNING) { > @@ -589,16 +649,14 @@ The callout function should first check > .Em pending > flag and return without action if > .Fn callout_pending > -returns > -.Dv TRUE . > +returns non-zero. > This indicates that the callout was rescheduled using > .Fn callout_reset > just before the callout function was invoked. > If > .Fn callout_active > -returns > -.Dv FALSE > -then the callout function should also return without action. > +returns zero then the callout function should also return without > +action. > This indicates that the callout has been stopped. > Finally, the callout function should call > .Fn callout_deactivate > @@ -668,129 +726,13 @@ a callout should always be drained prior > or releasing the storage for the callout structure. > .Sh LEGACY API > .Bf Sy > -The functions below are a legacy API that will be removed in a future release. > -New code should not use these routines. > -.Ef > -.Pp > -The function > -.Fn timeout > -schedules a call to the function given by the argument > -.Fa func > -to take place after > -.Fa ticks Ns No /hz > -seconds. > -Non-positive values of > -.Fa ticks > -are silently converted to the value > -.Sq 1 . > -.Fa func > -should be a pointer to a function that takes a > -.Fa void * > -argument. > -Upon invocation, > -.Fa func > -will receive > -.Fa arg > -as its only argument. > -The return value from > +The > .Fn timeout > -is a > -.Ft struct callout_handle > -which can be used in conjunction with the > -.Fn untimeout > -function to request that a scheduled timeout be canceled. > -.Pp > -The function > -.Fn callout_handle_init > -can be used to initialize a handle to a state which will cause > -any calls to > -.Fn untimeout > -with that handle to return with no side > -effects. > -.Pp > -Assigning a callout handle the value of > -.Fn CALLOUT_HANDLE_INITIALIZER > -performs the same function as > -.Fn callout_handle_init > -and is provided for use on statically declared or global callout handles. > -.Pp > -The function > -.Fn untimeout > -cancels the timeout associated with > -.Fa handle > -using the > -.Fa func > and > -.Fa arg > -arguments to validate the handle. > -If the handle does not correspond to a timeout with > -the function > -.Fa func > -taking the argument > -.Fa arg > -no action is taken. > -.Fa handle > -must be initialized by a previous call to > -.Fn timeout , > -.Fn callout_handle_init , > -or assigned the value of > -.Fn CALLOUT_HANDLE_INITIALIZER "&handle" > -before being passed to > -.Fn untimeout . > -The behavior of calling > .Fn untimeout > -with an uninitialized handle > -is undefined. > -.Pp > -As handles are recycled by the system, it is possible (although unlikely) > -that a handle from one invocation of > -.Fn timeout > -may match the handle of another invocation of > -.Fn timeout > -if both calls used the same function pointer and argument, and the first > -timeout is expired or canceled before the second call. > -The timeout facility offers O(1) running time for > -.Fn timeout > -and > -.Fn untimeout . > -Timeouts are executed from > -.Fn softclock > -with the > -.Va Giant > -lock held. > -Thus they are protected from re-entrancy. > -.Sh RETURN VALUES > -The > -.Fn callout_active > -macro returns the state of a callout's > -.Em active > -flag. > -.Pp > -The > -.Fn callout_pending > -macro returns the state of a callout's > -.Em pending > -flag. > -.Pp > -The > -.Fn callout_reset > -and > -.Fn callout_schedule > -function families return non-zero if the callout was pending before the new > -function invocation was scheduled. > -.Pp > -The > -.Fn callout_stop > -and > -.Fn callout_drain > -functions return non-zero if the callout was still pending when it was > -called or zero otherwise. > -The > -.Fn timeout > -function returns a > -.Ft struct callout_handle > -that can be passed to > -.Fn untimeout . > +functions are a legacy API that will be removed in a future release. > +New code should not use these routines. > > *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** > _______________________________________________ > svn-src-head@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/svn-src-head > To unsubscribe, send any mail to "svn-src-head-unsubscribe@freebsd.org"