msgport.9: lwkt_initport_spin now takes a fixed_cpuid argument.
[dragonfly.git] / share / man / man9 / msgport.9
1 .\"
2 .\" Copyright (c) 2012-2014 The DragonFly Project.  All rights reserved.
3 .\"
4 .\" This code is derived from software contributed to The DragonFly Project
5 .\" by Nuno Antunes <nuno.antunes@gmail.com>.
6 .\"
7 .\" Redistribution and use in source and binary forms, with or without
8 .\" modification, are permitted provided that the following conditions
9 .\" are met:
10 .\"
11 .\" 1. Redistributions of source code must retain the above copyright
12 .\"    notice, this list of conditions and the following disclaimer.
13 .\" 2. Redistributions in binary form must reproduce the above copyright
14 .\"    notice, this list of conditions and the following disclaimer in
15 .\"    the documentation and/or other materials provided with the
16 .\"    distribution.
17 .\" 3. Neither the name of The DragonFly Project nor the names of its
18 .\"    contributors may be used to endorse or promote products derived
19 .\"    from this software without specific, prior written permission.
20 .\"
21 .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 .\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25 .\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 .\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 .\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 .\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 .\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 .\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 .\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 .\" SUCH DAMAGE.
33 .\"
34 .Dd July 16, 2014
35 .Dt MSGPORT 9
36 .Os
37 .Sh NAME
38 .Nm lwkt_initport_thread ,
39 .Nm lwkt_initport_spin ,
40 .Nm lwkt_initport_serialize ,
41 .Nm lwkt_initport_panic ,
42 .Nm lwkt_initport_replyonly_null ,
43 .Nm lwkt_initport_replyonly ,
44 .Nm lwkt_initport_putonly ,
45 .Nm lwkt_sendmsg ,
46 .Nm lwkt_domsg ,
47 .Nm lwkt_forwardmsg ,
48 .Nm lwkt_abortmsg ,
49 .Nm lwkt_initmsg ,
50 .Nm lwkt_initmsg_abortable ,
51 .Nm lwkt_beginmsg ,
52 .Nm lwkt_replymsg ,
53 .Nm lwkt_getport ,
54 .Nm lwkt_waitport ,
55 .Nm lwkt_waitmsg ,
56 .Nm lwkt_checkmsg ,
57 .Nm lwkt_dropmsg
58 .Nd LWKT message passing interface
59 .Sh SYNOPSIS
60 .In sys/msgport.h
61 .Ft void
62 .Fn lwkt_initport_thread "lwkt_port_t port" "struct thread *td"
63 .Ft void
64 .Fn lwkt_initport_spin "lwkt_port_t port" "struct thread *td" "boolean_t fixed_cpuid"
65 .Ft void
66 .Fn lwkt_initport_serialize "lwkt_port_t port" "struct lwkt_serialize *slz"
67 .Ft void
68 .Fn lwkt_initport_panic "lwkt_port_t port"
69 .Ft void
70 .Fn lwkt_initport_replyonly_null "lwkt_port_t port"
71 .Ft void
72 .Fn lwkt_initport_replyonly "lwkt_port_t port" "void (*rportfn)(lwkt_port_t, lwkt_msg_t)"
73 .Ft void
74 .Fn lwkt_initport_putonly "lwkt_port_t port" "int (*pportfn)(lwkt_port_t, lwkt_msg_t)"
75 .Ft void
76 .Fn lwkt_sendmsg "lwkt_port_t port" "lwkt_msg_t msg"
77 .Ft int
78 .Fn lwkt_domsg "lwkt_port_t port" "lwkt_msg_t msg" "int flags"
79 .Ft int
80 .Fn lwkt_forwardmsg "lwkt_port_t port" "lwkt_msg_t msg"
81 .Ft void
82 .Fn lwkt_abortmsg "lwkt_msg_t msg"
83 .In sys/msgport2.h
84 .Ft void
85 .Fn lwkt_initmsg "lwkt_msg_t msg" "lwkt_port_t rport" "int flags"
86 .Ft void
87 .Fn lwkt_initmsg_abortable "lwkt_msg_t msg" "lwkt_port_t rport" "int flags" "void (*abortfn)(lwkt_msg_t)"
88 .Ft int
89 .Fn lwkt_beginmsg "lwkt_port_t port" "lwkt_msg_t msg"
90 .Ft void
91 .Fn lwkt_replymsg "lwkt_msg_t msg" "int error"
92 .Ft void *
93 .Fn lwkt_getport "lwkt_port_t port"
94 .Ft void *
95 .Fn lwkt_waitport "lwkt_port_t port" "int flags"
96 .Ft int
97 .Fn lwkt_waitmsg "lwkt_msg_t msg" "int flags"
98 .Ft int
99 .Fn lwkt_checkmsg "lwkt_msg_t msg"
100 .Ft int
101 .Fn lwkt_dropmsg "lwkt_msg_t msg"
102 .Sh DESCRIPTION
103 Light weight kernel threads in
104 .Dx
105 may use a message passing interface to communicate with each other.
106 Messages are sent to message ports.
107 All light weight kernel threads have a built-in message port, but you may create
108 additional ports if necessary.
109 The following types of message ports are available:
110 .Bl -bullet
111 .It
112 thread ports
113 .It
114 spin ports
115 .It
116 serializer ports
117 .El
118 .Pp
119 Ports of type
120 .Sq thread
121 are owned by a single light weight kernel thread.
122 When a message is sent to a port of type
123 .Sq thread ,
124 only the owner of that port is allowed to retrieve the message from it.
125 When a message is sent to a port of type
126 .Sq spin
127 or to a port of type
128 .Sq serializer ,
129 multiple threads are allowed to check that port for new
130 messages and compete to retrieve them.
131 You define the port type when you initialize the port.
132 By default, the built-in port of every light weight kernel thread is
133 automatically initialized to type
134 .Sq thread .
135 .Pp
136 When a message is sent, the receiver should normally send back a reply.
137 The reply is sent to the reply port that is registered on the original message.
138 Messages can be replied to synchronously or asynchronously.
139 The sender may request a synchronous or asynchronous reply to the message,
140 however the target port will ultimately decide how the message will be treated.
141 .Sh MESSAGE FUNCTIONS
142 Messages must be initialized before being used.
143 The
144 .Fn lwkt_initmsg
145 function initializes a message.
146 The
147 .Fa rport
148 argument identifies the reply port which will be used for asynchronous replies.
149 The
150 .Fa flags
151 argument sets any required flags for this message.
152 Flags passed this way will simply be or'ed to any already existing flags on the
153 message.
154 .Pp
155 The
156 .Fn lwkt_initmsg_abortable
157 function is similar to
158 .Fn lwkt_initmsg
159 but it takes an additional parameter
160 .Fa abortfn
161 which defines the abort function for this message.
162 .Pp
163 The
164 .Fn lwkt_sendmsg
165 function requests an asynchronous reply, sends the message and returns
166 immediately.
167 Under normal circumstances, users of this function may always expect the reply
168 to be queued to the reply port registered on the message.
169 The
170 .Fa port
171 argument defines the target port to which the
172 .Fa msg
173 message will be sent.
174 .Pp
175 The
176 .Fn lwkt_domsg
177 function requests a synchronous reply, sends the message and does not return
178 until the message has been replied to.
179 If the target port supports synchronous reply, this function will return that
180 reply immediately.
181 If not, and this is the most common case, this function will block and wait for the
182 reply to arrive and then return it.
183 The
184 .Fa port
185 argument defines the target port to which the
186 .Fa msg
187 message will be sent.
188 .Pp
189 The
190 .Fn lwkt_replymsg
191 function replies to a message that was processed asynchronously by the target
192 port.
193 This function is used by the thread on the receiving side.
194 The
195 .Fa msg
196 argument is the message being replied to and the
197 .Fa error
198 argument is the actual response to send back.
199 .Pp
200 The
201 .Fn lwkt_forwardmsg
202 simply forwards a message to another port.
203 The
204 .Fa port
205 argument defines the target port to which the
206 .Fa msg
207 message will be sent.
208 .Pp
209 If a message has been initialized as abortable, you can use the
210 .Fn lwkt_abortmsg
211 function to try to abort it.
212 The
213 .Fa abortfn
214 passed upon the initialisation with
215 .Fn lwkt_initmsg_abortable
216 will be called by this function.
217 .Pp
218 The
219 .Fn lwkt_dropmsg
220 will dequeue the specified message from the target port it was sent to and makes
221 it look like it was never sent.
222 This function can only be used by the thread that owns the target port.
223 .Sh PORT FUNCTIONS
224 The
225 .Fn lwkt_initport_thread
226 initializes the specified
227 .Fa port
228 with the default
229 .Sq thread
230 port type handlers.
231 The
232 .Fa td
233 argument defines the owner thread of the port and only that thread is allowed to
234 receive messages on it.
235 .Pp
236 The
237 .Fn lwkt_initport_spin
238 initializes the specified
239 .Fa port
240 with the default
241 .Sq spin
242 port type handlers.
243 The
244 .Fa td
245 argument defines the owner thread of the port, for cases where thread built-in
246 ports are initialized as
247 .Sq spin
248 ports.
249 If
250 .Dv NULL
251 is passed, then the port will not have a defined owner, so functions like
252 .Fn lwkt_dropmsg
253 will not be available for this port.
254 If we know that this
255 .Sq spin
256 port is accessed exclusively by threads on a single CPU, we can set the
257 .Fa fixed_cpuid
258 argument to true, which will prevent the occurrence of unnecessary IPIs trying
259 to wake up threads on other CPUs.
260 This function will also initialize the embedded spinlock within the
261 .Vt lwkt_port
262 structure which will protect subsequent port access.
263 .Pp
264 The
265 .Fn lwkt_initport_serialize
266 function initializes the specified
267 .Fa port
268 with the default
269 .Sq serializer
270 port type handlers.
271 The subsequent port access will be protected by the passed
272 .Fa slz
273 serializer lock.
274 .Pp
275 The
276 .Fn lwkt_getport
277 function checks the specified
278 .Fa port
279 for available messages, dequeues the first one and returns it.
280 If no messages are available then
281 .Dv NULL
282 is returned instead.
283 This function is used by threads on the receiving side.
284 .Pp
285 The
286 .Fn lwkt_waitport
287 function checks the specified
288 .Fa port
289 for available messages, dequeues the first one and returns it.
290 If no messages are available then the caller thread will sleep until a message
291 arrives on the specified port.
292 The
293 .Fa flags
294 argument defines the flags used for the sleep.
295 This function is used by threads on the receiving side.
296 .Sh SPECIAL PORT INITIALIZERS
297 The
298 .Fn lwkt_initport_replyonly
299 function initializes a
300 .Fa port
301 which is used only as reply port and may have a custom reply port handler.
302 The reply port handler is specified with the
303 .Fa rportfn
304 argument.
305 All the other handlers will panic the system if they are called.
306 This initializer is normally used on ports for freeing resources after the
307 messages have fulfilled their purpose.
308 .Pp
309 The
310 .Fn lwkt_initport_replyonly_null
311 function initializes a
312 .Fa port
313 which is used only as reply port.
314 The reply port handler will simply mark the message as being done and will not
315 attempt to queue it.
316 All the other handlers will panic the system if they are called.
317 .Pp
318 The
319 .Fn lwkt_initport_putonly
320 function initializes a
321 .Fa port
322 which is used only as target port.
323 The putport handler is specified with the
324 .Fa pportfn
325 argument.
326 All the other handlers will panic the system if they are called.
327 .Pp
328 The
329 .Fn lwkt_initport_panic
330 function initializes a
331 .Fa port
332 which will panic the system if any of its handlers are called.
333 This function is sometimes used to initialize a reply-only port which does not
334 expect the messages to be replied to, e.g.\& when the messages should be
335 consumed by the receiving thread and never replied back.
336 .Sh INTERNAL MESSAGE FUNCTIONS
337 The following functions are used only by the infrastructure, you should not
338 need to use them directly unless in very rare cases.
339 .Pp
340 The
341 .Fn lwkt_beginmsg
342 function simply calls the target port's putport handler.
343 This function is only called by the
344 .Fn lwkt_sendmsg
345 and
346 .Fn lwkt_replymsg
347 functions.
348 The putport handler returns
349 .Er EASYNC
350 for messages processed asynchronously or any other value for messages processed
351 synchronously.
352 That return value of the putport handler is propagated by this function.
353 The
354 .Fa port
355 argument defines the target port to which the
356 .Fa msg
357 message will be sent.
358 .Pp
359 The
360 .Fn lwkt_waitmsg
361 function puts the caller to sleep until the specified
362 .Fa msg
363 message has been replied to.
364 The
365 .Fa flags
366 argument defines the flags used for the sleep.
367 .Sh IMPLEMENTATION NOTES
368 All the default putport handlers (used when a message is sent) currently
369 implement asynchronous putports only, i.e.\& all
370 .Fn *_putport
371 handlers return
372 .Er EASYNC .
373 You can still have synchronous putport handlers (which are run in the sender's
374 context) but you have to implement the function yourself and then override the
375 default.
376 .Pp
377 Port handler functions can be overridden with custom functions if required.
378 You can override the default putport handler by either using the
379 .Fn lwkt_initport_putonly
380 initializer, or by manipulating the mp_putport handler pointer directly on the
381 .Vt lwkt_port
382 structure.
383 .Pp
384 There is one such case where the putport handler is overridden in
385 .Pa sys/net/netisr.c .
386 In that case, the putport handler is overridden to detect a loopback message
387 (when the target port belongs to the sending thread).
388 This special putport handler turns the sent message into a direct function call
389 instead of queueing it to the port.
390 .Pp
391 The
392 .Fn lwkt_replymsg
393 function works differently depending on the original message request.
394 If the
395 message was originally an asynchronous request, the reply will be queued to the
396 sender's reply port.
397 If the message was originally a synchronous request, then
398 this function will just write the error response on the message and wake up the
399 waiter without queueing the message to the reply port.
400 There is no need to queue in the synchronous request case because the original
401 sender had blocked waiting on this specific message with
402 .Fn lwkt_domsg .
403 .Pp
404 As is the case with putport handler, the replyport handler can also be
405 overridden.
406 You override the default replyport handler by using the
407 .Fn lwkt_initport_replyonly
408 or the
409 .Fn lwkt_initport_replyonly_null
410 port initializers, or by manipulating the mp_replyport handler pointer directly
411 on the
412 .Vt lwkt_port
413 structure.
414 .Pp
415 The sent message structure is reused for replies.
416 When a message is replied to, the error response is written on the message
417 which is subsequently sent to the reply port.
418 .Sh FILES
419 The LWKT msgport implementation resides in
420 .Pa sys/kern/lwkt_msgport.c .
421 .Sh EXAMPLES
422 .Bd -literal
423 /*
424  * Example 1: per CPU threads.
425  *
426  */
427
428 #include <sys/thread.h>
429 #include <sys/msgport.h>
430 #include <sys/msgport2.h>
431
432 static void my_service_loop(void *dummy);
433 lwkt_port_t my_service_portfn(int cpu);
434 void my_service_sendmsg(lwkt_msg_t lmsg, int cpu);
435 int my_service_domsg(lwkt_msg_t lmsg, int cpu);
436
437 /* Array of per-CPU target ports */
438 struct lwkt_port *my_service_ports[MAXCPU];
439
440 /*
441  * Create per-cpu threads for handling msg processing.  Remember that
442  * built-in lwkt ports are automatically initialized to type 'thread'
443  * so we don't need to initialize them explicitly.
444  */
445 static void
446 my_per_cpu_service_init(void)
447 {
448         int i;
449         thread_t td;
450
451         for (i = 0; i < ncpus; ++i) {
452                 lwkt_create(my_service_loop, NULL, &td,
453                             NULL, 0, i, "myservice_cpu %d", i);
454                 my_service_ports[i] = &td->td_msgport;
455         }
456 }
457
458 /*
459  * This is the routine executed by the service threads on each CPU.
460  */
461 static void
462 my_service_loop(void *dummy __unused)
463 {
464         lwkt_msg_t msg;
465         thread_t td = curthread;
466         int cpu = curthread->td_gd->gd_cpuid;
467
468         while ((msg = lwkt_waitport(&td->td_msgport, 0)) != NULL) {
469                 /* Do some work in the receiver thread context. */
470                 kprintf("Received message on CPU %d.\en", cpu);
471
472                 /* And finally reply to the message. */
473                 lwkt_replymsg(msg, 0);
474         }
475 }
476
477 /*
478  * Given a CPU id, return our respective service port.
479  */
480 __inline lwkt_port_t
481 my_service_portfn(int cpu)
482 {
483         return my_service_ports[cpu];
484 }
485
486 /*
487  * Send an asynchronous message to the service thread on a specific CPU.
488  */
489 void
490 my_service_sendmsg(lwkt_msg_t lmsg, int cpu)
491 {
492         KKASSERT(cpu < ncpus);
493         lwkt_sendmsg(my_service_portfn(cpu), lmsg);
494 }
495
496 /*
497  * Send a synchronous message to the service thread on a specific CPU.
498  */
499 int
500 my_service_domsg(lwkt_msg_t lmsg, int cpu)
501 {
502         KKASSERT(cpu < ncpus);
503         return lwkt_domsg(my_service_portfn(cpu), lmsg, 0);
504 }
505
506 /*
507  * Example use case. Initialize the service threads and send each one a
508  * message.
509  */
510 static void
511 mod_load(void)
512 {
513         lwkt_msg        lmsg;
514         lwkt_port_t     builtin_port = &curthread->td_msgport;
515         int             i;
516
517         my_per_cpu_service_init();
518         for (i=0; i<ncpus; ++i) {
519                 kprintf("Sending msg to CPU %d.\en", i);
520                 lwkt_initmsg(&lmsg, builtin_port, 0);
521                 my_service_domsg(&lmsg, i);
522         }
523 }
524
525 /*
526  * Example 2: Dynamic allocated message passing with automatic free.
527  *
528  * This scenario is used when resources need to be freed after the
529  * message has been replied to. Features:
530  * - An argument is passed within the message.
531  * - Messages are allocated with kmalloc(). Replying to the message
532  *   kfree()s it.
533  */
534
535 #include <sys/thread.h>
536 #include <sys/msgport.h>
537 #include <sys/msgport2.h>
538
539 void my_service_queue(void *arg);
540
541 lwkt_port my_autofree_rport;
542 lwkt_port_t my_service_port;
543
544 /*
545  * Use this function to send messages with a void * argument to our
546  * service thread.
547  */
548 void
549 my_service_queue(void *arg)
550 {
551         lwkt_msg_t msg;
552
553         msg = kmalloc(sizeof(*msg), M_TEMP, M_WAITOK);
554
555         /* Set reply port to autofree. */
556         lwkt_initmsg(msg, &my_autofree_rport, 0);
557
558         /* Attach the argument to the message. */
559         msg->u.ms_resultp = arg;
560
561         /* Send it. */
562         lwkt_sendmsg(my_service_port, msg);
563 }
564
565 /*
566  * This is the routine executed by our service thread.
567  */
568 static void
569 my_service_loop(void *dummy __unused)
570 {
571         lwkt_msg_t msg;
572         thread_t td = curthread;
573
574         while ((msg = lwkt_waitport(&td->td_msgport, 0)) != NULL) {
575                 /*
576                  * Do some work in the receiver thread context.  In this
577                  * example, the sender wrote his name in the argument he
578                  * sent us.  We print it here.
579                  */
580                 char *arg = msg->u.ms_resultp;
581                 kprintf("%s: Hi %s! Got your msg.\en", curthread->td_comm,
582                     arg);
583
584                 /* And finally reply to the message. */
585                 lwkt_replymsg(msg, 0);
586         }
587 }
588
589 static void
590 my_autofree_reply(lwkt_port_t port, lwkt_msg_t msg)
591 {
592         kfree(msg->u.ms_resultp, M_TEMP);
593         kfree(msg, M_TEMP);
594 }
595
596 static void
597 my_service_init(void)
598 {
599         thread_t tdp;
600
601         /* Initialize our auto free reply port. */
602         lwkt_initport_replyonly(&my_autofree_rport, my_autofree_reply);
603
604         /* Create our service thread on CPU 0. */
605         lwkt_create(my_service_loop, NULL, &tdp, NULL, 0, 0, "myservice");
606         my_service_port = &tdp->td_msgport;
607 }
608
609 /*
610  * Example use case. Initialize the service and send the current thread
611  * name to the service thread.
612  */
613 static void
614 mod_load(void)
615 {
616         void *arg;
617         int len;
618
619         my_service_init();
620         len = strlen(curthread->td_comm);
621         arg = kmalloc(len + 1, M_TEMP, M_WAITOK);
622         bcopy(curthread->td_comm, arg, len + 1);
623         kprintf("%s: Sending message.\en", curthread->td_comm);
624         my_service_queue(arg);
625 }
626 .Ed
627 .Sh SEE ALSO
628 .Xr serializer 9 ,
629 .Xr sleep 9 ,
630 .Xr spinlock 9
631 .Sh HISTORY
632 The LWKT msgport interface first appeared in
633 .Dx 1.0 .
634 .Sh AUTHORS
635 .An -nosplit
636 The
637 .Nm msgport
638 message passing interface implementation was written by
639 .An Matthew Dillon .
640 This manual page was written by
641 .An Nuno Antunes .