bce: Disable RX max BDs based interrupt moderation
[dragonfly.git] / lib / libc / sys / upc_register.2
CommitLineData
a5ecd468
MD
1.\" Copyright (c) 2003 Matthew Dillon <dillon@backplane.com>
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\" notice, this list of conditions and the following disclaimer in the
11.\" documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
8a7bdfea 25.\" $DragonFly: src/lib/libc/sys/upc_register.2,v 1.10 2008/05/02 02:05:04 swildner Exp $
a5ecd468
MD
26.\"
27.Dd November 20, 2003
28.Dt UPC_REGISTER 2
29.Os
30.Sh NAME
31.Nm upc_register ,
32.Nm upc_control
33.Nd configure and control upcalls
34.Sh LIBRARY
35.Lb libc
36.Sh SYNOPSIS
37.In sys/upcall.h
38.Ft int
39.Fn upc_register "struct upcall *upc" "upcall_func_t ctxfunc" "upcall_func_t cfunc" "void *data"
40.Ft int
41.Fn upc_control "int command" "int upcall_id" "void *data"
42.Sh DESCRIPTION
a559210f
HP
43The
44.Fn upc_register
45function
46registers an upcall.
47Note that the specified upcall structural pointer
48is per-process, not per-upcall.
49It points to a structure in user memory
a5ecd468
MD
50that both the user and kernel manipulate to deal with upcall/critical-section
51interlocks.
52.Fa ctxfunc
a559210f
HP
53is a pointer to context save and restore code.
54The native upcall interface
55does not necessarily save and restore call-used registers.
56This function
a5ecd468 57is typically written in assembly and supplied by
e38a3020 58.Em libc .
a5ecd468
MD
59.Fa cfunc
60is a pointer to a C style function and
61.Fa data
a559210f
HP
62is the data passed to it as an argument.
63A positive upcall identifier
64will be returned or -1 if an error occurred.
a5ecd468
MD
65.Pp
66When an upcall is executed the
a559210f 67kernel will add
de1a0a27 68.Dv TDPRI_CRIT
a559210f 69to the critical section count in the upcall
a5ecd468
MD
70structure, push a minimal context (not even call-used), and pass the C
71function and data pointers to
72.Fa ctxfunc
73in registers.
1bf4b486
SW
74.Fa ctxfunc
75will then proceed to save appropriate state, call the C function, and
a559210f
HP
76deal with cleanup.
77Cleanup typically involves an interlocking operation
a5ecd468 78and a call to
a559210f 79.Fn upc_control
a5ecd468
MD
80in order to undo the critical section count and process any additional
81pending upcalls atomically.
82.Fa ctxfunc
83will typically pop most of its state, set upcall->pending to 1,
a559210f 84subtract
de1a0a27 85.Dv TDPRI_CRIT
1bf4b486 86from upcall->crit_count, and call
a5ecd468
MD
87.Fn upc_control "UPC_CONTROL_NEXT" "-1" "stack_pointer"
88which atomically handles any further pending upcalls and/or pops the
89original stack context supplied to
90.Fn upc_control
a559210f
HP
91and resumes the originally interrupted code.
92This is all very complex which is why
e38a3020 93.Em libc
a5ecd468
MD
94typically supplies
95.Fa ctxfunc .
96.Pp
97Note that upcalls can only occur if the target process is not in a critical
a559210f
HP
98section.
99If an upcall cannot be dispatched it will instead be made pending
a5ecd468 100and the pending field in the user-supplied upcall structure will be set to
a559210f
HP
101non-zero.
102Userland critical-section-exiting code must check the pending
a5ecd468
MD
103bit and call the appropriate
104.Fn upc_control
105function to handle any pending upcalls.
106.Pp
a559210f
HP
107The upcall identifier space is shared amongst all processes sharing the
108same VM space.
109That is, all the processes created through
110.Fn clone
111or
112.Fn rfork "RFMEM" .
113Through appropriate
a5ecd468
MD
114.Fn upc_control
115calls any process within this domain can generate an upcall on any other
a559210f 116process within this domain, including itself.
1bf4b486 117Each process typically
a5ecd468
MD
118installs a different (per-process) upcall data structure.
119.Pp
a559210f
HP
120The
121.Fn upc_control
122function,
a5ecd468
MD
123is a multi-function system call capable of dispatching upcalls, handling
124the context assembly function's interlocks, deleting upcalls, and polling
125for upcalls.
126.Pp
127.Ft int
093dd88e 128.Fn upc_control "UPC_CONTROL_DISPATCH" "upcid" "(int)priority"
3bdb37ee 129.Bd -literal -offset indent
a559210f
HP
130Dispatch a particular upcall.
131The value
132.Li 0
133is returned on success,
134.Er ENOENT
135if
a5ecd468 136.Fa upcid
a559210f
HP
137does not exist.
138You can dispatch upcalls belonging to your process or
139to another process.
140You may specify a
a5ecd468
MD
141.Fa upcid
142of -1 to re-dispatch the first upcall owned by your own process that is
a559210f
HP
143pending from a previous operation.
144Note that that critical section and
a5ecd468
MD
145pending rules apply, and an actual dispatch will pushdown the stack.
146.Pp
093dd88e
MD
147The priority will be compared against the current crit_count to determine
148whether the upcall dispatches or is made pending.
149.Pp
a5ecd468
MD
150This command is most often used to alert a target process to a change in
151a shared structure, queue, etc.
152.Ed
153.Pp
154.Ft int
155.Fn upc_control "UPC_CONTROL_NEXT" "-1" "stack_pointer"
3bdb37ee 156.Bd -literal -offset indent
a559210f
HP
157Do interlocking and stack munging to process additional upcalls.
158This
a5ecd468
MD
159system call should never be made directly by C code because it expects
160all registers not saved by the operating system in entering a context
161function to have been popped and a pointer to the base of the OS-supplied
a559210f
HP
162stack context on entry to the context routine to be supplied.
163This routine
a5ecd468
MD
164does not return to the caller but instead either regenerates the stack
165context for the next pending upcall or it restores the original context,
166resuming whomever was interrupted by the original upcall that entered the
167context routine.
168.Ed
169.Pp
170.Ft int
171.Fn upc_control "UPC_CONTROL_DELETE" "upcid" "NULL"
3bdb37ee 172.Bd -literal -offset indent
a5ecd468
MD
173Delete the specified
174.Fa upcid
175or, if -1 is specified, delete all upcall registered by the current process.
176If -1 is specified, the upcalls registered by another process will not be
a559210f
HP
177deleted.
178If a particular
a5ecd468
MD
179.Fa upcid
180is specified, it will be deleted regardless of which process registered it.
1bf4b486 181The upcall structural pointer registered with this or any other process is
a5ecd468
MD
182not effected.
183.Ed
184.Pp
185.Ft int
186.Fn upc_control "UPC_CONTROL_POLL" "upcid" "NULL"
187.Pp
188.Ft int
093dd88e 189.Fn upc_control "UPC_CONTROL_POLLANDCLEAR" "upcid" "(int)priority"
3bdb37ee 190.Bd -literal -offset indent
a559210f
HP
191Poll or poll-and-clear the pending status for a particular upcall.
192The value
193.Li 0
194or
195.Li 1
196is returned, or
197.Li -1
198if an error occurred (e.g.
1bf4b486 199.Er ENOENT ).
a5ecd468
MD
200If a
201.Fa upcid
202of -1 is specified, locate a pending upcall for the current process and return
203it's
204.Fa upcid ,
205or 0 if no upcalls for the current process are pending.
093dd88e 206.Pp
a559210f
HP
207The priority will be compared against the upcall's pending priority.
208Only
093dd88e
MD
209upcalls with greater or equal pending priorities are returned. You must
210specify a minimum priority of 1 or this call will simply return a random
211registered upcall that may or may not be pending.
a5ecd468
MD
212.Ed
213.Pp
214.Bd -literal -offset indent -compact
215struct upcall {
216 int magic; /* must be UPCALL_MAGIC */
217 int crit_count; /* critical section count */
218 int pending; /* additional upcalls are pending */
219};
220.Ed
221.Pp
1bf4b486 222This is a user space structure a pointer to which is registered with the
a5ecd468
MD
223kernel via
224.Fn upc_register
225\.
226The
227.Fa crit_count
a559210f 228field prevents new upcalls from being dispatched.
1bf4b486 229When an upcall is
a5ecd468 230dispatched the kernel automatically adds
a559210f 231.Dv UPC_CRITADD
1bf4b486 232to
a5ecd468
MD
233.Fa crit_count
234and sets
235.Fa pending
a559210f
HP
236to indicate whether any additional upcalls are pending.
237A non-zero
a5ecd468
MD
238.Fa pending
239OR
240.Fa crit_count
a559210f
HP
241will prevent new upcalls from the being dispatched.
242The context function
a5ecd468 243code is expected to make appropriate checks to dispatch any remaining upcalls
a559210f
HP
244when the current upcall has completed.
245In particular, the context function
a5ecd468
MD
246must subtract
247.Va UPC_CRITADD
1bf4b486 248from
a5ecd468
MD
249.Fa crit_count
250before restoring the original context or calling
251.Fn upc_control "UPC_CONTROL_NEXT" "..."
252\.
253Note that
254.Fa pending
255may be set as a side effect to various
256.Fn upc_control
257system calls as well as as a side effect to upcall dispatches.
258.Pp
259Userland threading code typically uses
260.Fa crit_count
a559210f
HP
261to control critical sections within a virtual CPU (i.e., cloned process).
262Entering a critical section is as simply as add
263.Dv UPC_CRITADD
264to
a5ecd468
MD
265.Fa crit_count .
266No atomic or locked instructions are required as this field is accessed
267only by the current process and any upcalls or interrupts will restore it
a559210f
HP
268to the condition they found it before returning.
269Exiting a critical section
270is almost as simple as subtracting
271.Dv UPC_CRITADD
272from
a5ecd468
MD
273.Fa crit_count .
274The routine which performs this function must also check the
275.Fa pending
a559210f
HP
276field once the critical section count has reached 0.
277If the pending field
a5ecd468
MD
278is non-zero, the routine will generally call
279.Fn upc_control "UPC_CONTROL_DISPATCH" "-1" "NULL"
280to dispatch upcalls which were made pending while you were in the critical
281section.
282.Sh CONTEXT FUNCTION - IA32
1bf4b486 283The context function is called with the stack pointer pointing at a
a559210f
HP
284kernel-constructed stack frame.
285Only a minimal number of registers are
1bf4b486 286saved by the kernel.
a5ecd468
MD
287.Pp
288.Bd -literal -offset indent -compact
289frame {
290 int32_t eax;
291 int32_t ecx;
0a455ac5 292 int32_t edx;
a5ecd468
MD
293 int32_t eflags;
294 int32_t origip;
295}
296.Ed
297.Pp
a559210f 298On entry, %eax will hold the C function pointer, %ecx will hold the
0a455ac5 299C data pointer, and %edx will hold a pointer to the user-supplied upcall
a559210f
HP
300structure.
301The context code does not need to push %eax, %ecx, or %edx
0a455ac5
MD
302because these registers have already been pushed on the stack for it, but
303it must generally push any remaining registers that it might use and be
304careful in regards to others, such as floating point registers, which
a559210f
HP
305the OS has not saved.
306The operating system has already adjusted the
a5ecd468
MD
307.Fa crit_count
308and
309.Fa pending
310fields in the user-supplied
311.Fa upcall
312structure, so the context code will generally next push the data pointer
a559210f
HP
313(%ecx) and call the C function through %eax.
314Upon return the context code
a5ecd468
MD
315is responsible for interlocking the upcall return which it does by first
316setting
317.Fa pending
318to 1, then subtracting
319.Va UPC_CRITADD
320from
321.Fa crit_count ,
322then restoring its part of the context but leaving the OS context intact,
323then calling
324.Fn upc_control "UPC_CONTROL_NEXT" "-1" "stack_pointer_to_OS_context"
325\.
a559210f
HP
326The control function will not return.
327It will either restart the context
a5ecd468
MD
328at the next upcall, if more are pending, or it will restore the original
329context.
330.Pp
a559210f
HP
331The context code does not have to follow this regime.
332There is nothing
a5ecd468
MD
333preventing the context code from restoring the original frame itself and
334returning directly to the originally interrupted user code without having
a559210f
HP
335to make another kernel transition.
336It is possible to optimize this by
a5ecd468
MD
337having the context code subtract down
338.Va UPC_CRITADD
339as per normal but not pre-set the
340.Fa pending
341field. If it does this and
1bf4b486 342.Fa pending
a5ecd468
MD
343is 0, it is possible for the kernel to initiate another upcall before
344the context code has had a chance to pop its stack and restore the original
a559210f
HP
345user context.
346This is OK under controlled circumstances.
347On the other hand,
a5ecd468 348if
1bf4b486 349.Fa pending
a5ecd468
MD
350is 1
351the context code knows there is another upcall pending and can call
352.Fn upc_control
353as appropriate.
354.Pp
355.Bd -literal -offset indent -compact
356 /*
357 * upc is a global pointing to this process's upcall structure
358 * (just as an example). The Os-supplied stack frame is:
359 *
0a455ac5 360 * [%eax %ecx %edx,%eflags %original_ip]
a5ecd468
MD
361 */
362callused_wrapper:
0a455ac5 363 pushl %edx /* save %edx (upcall pointer) */
a5ecd468
MD
364 pushl %ecx /* func=%eax(data=%ecx) */
365 call *%eax /* call the C function */
366 addl $4,%esp
0a455ac5
MD
367 popl %edx /* restore the upcall pointer */
368 incl PENDING(%edx) /* setting pending stops upcalls */
369 subl $32,CRIT_COUNT(%edx) /* cleanup crit section count */
a5ecd468
MD
370 pushl %esp /* sp pointing to os user frame */
371 pushl $-1 /* upcid */
372 pushl $2 /* FETCH next */
373 call upc_control
374 /* not reached */
375 /* just for show, restore Os supplied user context */
376 popl %eax /* code just for show */
377 popl %ecx /* code just for show */
0a455ac5 378 popl %edx /* code just for show */
a5ecd468
MD
379 popfl /* code just for show */
380 ret /* code just for show */
381.Ed
a5ecd468 382.Sh ERRORS
a559210f
HP
383The
384.Fn upc_register
385function
386returns:
387.Bl -tag -width Er
a5ecd468 388.It Bq Er EFBIG
a559210f
HP
389if the kernel has reached its upcall registration limit.
390The limit is on a
391per-shared-vmspace basis and is no less then 32.
392Otherwise this function
a5ecd468
MD
393returns a non-zero, positive number indicating the upcall identifier that
394was registered.
395.Pp
a559210f
HP
396The
397.Fn upc_control
398function
a5ecd468
MD
399returns
400.It Bq Er ENOENT
401if a particular requested
402.Fa upcid
403cannot be found.
a559210f 404.El
a5ecd468 405.Sh SEE ALSO
a559210f 406.Xr rfork 2 ,
a5ecd468
MD
407.Xr clone 3
408.Sh HISTORY
409The
410.Fn upc_register
1bf4b486 411and
a5ecd468
MD
412.Fn upc_control
413function calls
414appeared in
a3220ac5 415.Dx 1.0 .