mdoc: Add a msgport(9) manual page documenting LWKT message passing interface.
[dragonfly.git] / share / man / man9 / msgport.9
1 .\"
2 .\" Copyright (c) 2012 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 August 12, 2012
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"
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 void
101 .Fn lwkt_dropmsg "lwkt_msg_t msg"
102 .Sh DESCRIPTION
103 Light weight kernel threads in DragonFly may use a message passing interface to
104 communicate with each other.
105 Messages are sent to message ports.
106 All light weight kernel threads have a built-in message port, but you may create
107 additional ports if necessary.
108 The following types of message ports are available:
109 .Bl -bullet
110 .It
111 thread ports
112 .It
113 spin ports
114 .It
115 serializer ports
116 .El
117 .Pp
118 Ports of type 'thread' are owned by a single light weight kernel thread.
119 When a message is sent to a port of type 'thread', only the owner of that port
120 is allowed to retrieve the message from it.
121 When a message is sent to a port of type 'spin' or to a port of
122 type 'serializer', multiple threads are allowed to check that port for new
123 messages and compete to retrieve them.
124 You define the port type when you initialize the port.
125 By default, the built-in port of every light weight kernel thread is
126 automatically initialized to type 'thread'.
127 .Pp
128 When a message is sent, the receiver should normally send back a reply.
129 The reply is sent to the reply port that is registered on the original message.
130 Messages can be replied to synchronously or asynchronously.
131 The sender may request a synchronous or asynchronous reply to the message,
132 however the target port will ultimately decide how the message will be treated.
133 .Sh MESSAGE FUNCTIONS
134 Messages must be initialized before being used.
135 The
136 .Fn lwkt_initmsg
137 function initializes a message.
138 The
139 .Fa rport
140 argument identifies the reply port which will be used for asynchronous replies.
141 The
142 .Fa flags
143 argument sets any required flags for this message.
144 Flags passed this way will simply be or'ed to any already existing flags on the
145 message.
146 .Pp
147 The
148 .Fn lwkt_initmsg_abortable
149 function is similar to
150 .Fn lwkt_initmsg
151 but it takes an additional parameter
152 .Fa abortfn
153 which defines the abort function for this message.
154 .Pp
155 The
156 .Fn lwkt_sendmsg
157 function requests an asynchronous reply, sends the message and returns
158 immediately.
159 Under normal circumstances, users of this function may always expect the reply
160 to be queued to the reply port registered on the message.
161 The
162 .Fa port
163 argument defines the target port to which the
164 .Fa msg
165 message will be sent to.
166 .Pp
167 The
168 .Fn lwkt_domsg
169 function requests a synchronous reply, sends the message and does not return
170 until the message has been replied to.
171 If the target port supports synchronous reply, this function will return that
172 reply immediately.
173 If not, and this is the most common case, this function will block and wait for the
174 reply to arrive and then return it.
175 The
176 .Fa port
177 argument defines the target port to which the
178 .Fa msg
179 message will be sent to.
180 .Pp
181 The
182 .Fn lwkt_replymsg
183 function replies to a message that was processed asynchronously by the target
184 port.
185 This function is used by the thread on the receiving side.
186 The
187 .Fa msg
188 argument is the message being replied to and the
189 .Fa error
190 argument is the actual response to send back.
191 .Pp
192 The
193 .Fn lwkt_forwardmsg
194 simply forwards a message to another port.
195 The
196 .Fa port
197 argument defines the target port to which the
198 .Fa msg
199 message will be sent to.
200 .Pp
201 If a message has been initialized as abortable, you can use the
202 .Fn lwkt_abortmsg
203 function to try to abort it.
204 The
205 .Fa abortfn
206 passed upon the initialisation with
207 .Fn lwkt_initmsg_abortable
208 will be called by this function.
209 .Pp
210 The
211 .Fn lwkt_dropmsg
212 will dequeue the specified message from the target port it was sent to and makes
213 it look like it was never sent.
214 .Sh PORT FUNCTIONS
215 The
216 .Fn lwkt_initport_thread
217 initializes the specified
218 .Fa port
219 with the default 'thread' port type handlers.
220 The
221 .Fa td
222 argument defines the owner thread of the port and only that thread is allowed to
223 receive messages on it.
224 .Pp
225 The
226 .Fn lwkt_initport_spin
227 initializes the specified
228 .Fa port
229 with the default 'spin' port type handlers.
230 It will also initialize the embedded spinlock within the
231 lwkt_port structure which will protect subsequent port access.
232 .Pp
233 The
234 .Fn lwkt_initport_serialize
235 function initializes the specified
236 .Fa port
237 with the default 'serializer' port type handlers.
238 The subsequent port access will be protected by the passed
239 .Fa slz
240 serializer lock.
241 .Pp
242 The
243 .Fn lwkt_getport
244 function checks the specified
245 .Fa port
246 for available messages, dequeues the first one and returns it.
247 If no messages are available then
248 .Dv NULL
249 is returned instead.
250 This function is used by threads on the receiving side.
251 .Pp
252 The
253 .Fn lwkt_waitport
254 function checks the specified
255 .Fa port
256 for available messages, dequeues the first one and returns it.
257 If no messages are available then the caller thread will sleep until a message
258 arrives on the specified port.
259 The
260 .Fa flags
261 argument defines the flags used for the sleep.
262 This function is used by threads on the receiving side.
263 .Sh SPECIAL PORT INITIALIZERS
264 The
265 .Fn lwkt_initport_replyonly
266 function initializes a
267 .Fa port
268 which is used only as reply port and may have a custom reply port handler.
269 The reply port handler is specified with the
270 .Fa rportfn
271 argument.
272 All the other handlers will panic the system if they are called.
273 This initializer is normally used on ports for freeing resources after the
274 messages have fulfilled their purpose.
275 .Pp
276 The
277 .Fn lwkt_initport_replyonly_null
278 function initializes a
279 .Fa port
280 which is used only as reply port.
281 The reply port handler will simply mark the message as being done and will not
282 attempt to queue it.
283 All the other handlers will panic the system if they are called.
284 .Pp
285 The
286 .Fn lwkt_initport_putonly
287 function initializes a
288 .Fa port
289 which is used only as target port.
290 The putport handler is specified with the
291 .Fa pportfn
292 argument.
293 All the other handlers will panic the system if they are called.
294 .Pp
295 The
296 .Fn lwkt_initport_panic
297 function initializes a
298 .Fa port
299 which will panic the system if any of its handlers are called.
300 This function is sometimes used to initialize a reply-only port which does not
301 expect the messages to be replied to, e.g. when the messages should be consumed
302 by the receiving thread and never replied back.
303 .Sh INTERNAL MESSAGE FUNCTIONS
304 The following functions are used only by the infrastructure, you should not
305 need to use them directly unless in very rare cases.
306 .Pp
307 The
308 .Fn lwkt_beginmsg
309 function simply calls the target port's putport handler.
310 This function is only called by the
311 .Fn lwkt_sendmsg
312 and
313 .Fn lwkt_replymsg
314 functions.
315 The putport handler returns
316 .Er EASYNC
317 for messages processed asynchronously or any other value for messages processed
318 synchronously.
319 That return value of the putport handler is propagated by this function.
320 The
321 .Fa port
322 argument defines the target port to which the
323 .Fa msg
324 message will be sent to.
325 .Pp
326 The
327 .Fn lwkt_waitmsg
328 function puts the caller to sleep until the specified
329 .Fa msg
330 message has been replied to.
331 The
332 .Fa flags
333 argument defines the flags used for the sleep.
334 .Sh FILES
335 The LWKT msgport implementation resides in
336 .Pa sys/kern/lwkt_msgport.c .
337 .Sh EXAMPLES
338 .Bd -literal
339 /*
340  * Example 1: per CPU threads.
341  *
342  */
343
344 #include <sys/thread.h>
345 #include <sys/msgport.h>
346 #include <sys/msgport2.h>
347
348 static void my_service_loop(void *dummy);
349 lwkt_port_t my_service_portfn(int cpu);
350 void my_service_sendmsg(lwkt_msg_t lmsg, int cpu);
351 int my_service_domsg(lwkt_msg_t lmsg, int cpu);
352
353 /* Array of per-CPU target ports */
354 struct lwkt_port *my_service_ports[MAXCPU];
355
356 /*
357  * Create per-cpu threads for handling msg processing.  Remember that built-in
358  * lwkt ports are automatically initialized to type 'thread' so we don't need
359  * to initialize them explicitly.
360  */
361 static void
362 my_per_cpu_service_init(void)
363 {
364         int i;
365         thread_t td;
366
367         for (i = 0; i < ncpus; ++i) {
368                 lwkt_create(my_service_loop, NULL, &td,
369                             NULL, 0, i, "myservice_cpu %d", i);
370                 my_service_ports[i] = &td->td_msgport;
371         }
372 }
373
374 /*
375  * This is the routine executed by the service threads on each CPU.
376  */
377 static void
378 my_service_loop(void *dummy __unused)
379 {
380         lwkt_msg_t msg;
381         thread_t td = curthread;
382         int cpu = curthread->td_gd->gd_cpuid;
383
384         while ((msg = lwkt_waitport(&td->td_msgport, 0)) != NULL) {
385                 /* Do some work in the receiver thread context. */
386                 kprintf("Received message on CPU %d.\en", cpu);
387
388                 /* And finally reply to the message. */
389                 lwkt_replymsg(msg, 0);
390         }
391 }
392
393 /*
394  * Given a CPU id, return our respective service port.
395  */
396 __inline lwkt_port_t
397 my_service_portfn(int cpu)
398 {
399         return my_service_ports[cpu];
400 }
401
402 /*
403  * Send an asynchronous message to the service thread on a specific CPU.
404  */
405 void
406 my_service_sendmsg(lwkt_msg_t lmsg, int cpu)
407 {
408         KKASSERT(cpu < ncpus);
409         lwkt_sendmsg(my_service_portfn(cpu), lmsg);
410 }
411
412 /*
413  * Send a synchronous message to the service thread on a specific CPU.
414  */
415 int
416 my_service_domsg(lwkt_msg_t lmsg, int cpu)
417 {
418         KKASSERT(cpu < ncpus);
419         return lwkt_domsg(my_service_portfn(cpu), lmsg, 0);
420 }
421
422 /*
423  * Example use case. Initialize the service threads and send each one a
424  * message.
425  */
426 static void
427 mod_load(void)
428 {
429         lwkt_msg        lmsg;
430         lwkt_port_t     builtin_port = &curthread->td_msgport;
431         int             i;
432
433         my_per_cpu_service_init();
434         for (i=0; i<ncpus; ++i) {
435                 kprintf("Sending msg to CPU %d.\en", i);
436                 lwkt_initmsg(&lmsg, builtin_port, 0);
437                 my_service_domsg(&lmsg, i);
438         }
439 }
440
441 /*
442  * Example 2: Dynamic allocated message passing with automatic free.
443  *
444  * This scenario is used when resources need to be freed after the message
445  * has been replied to. Features:
446  * - An argument is passed within the message.
447  * - Messages are allocated with kmalloc(). Replying to the msg, kfree()s it.
448  */
449
450 #include <sys/thread.h>
451 #include <sys/msgport.h>
452 #include <sys/msgport2.h>
453
454 void my_service_queue(void *arg);
455
456 lwkt_port my_autofree_rport;
457 lwkt_port_t my_service_port;
458
459 /*
460  * Use this function to send messages with a void * argument to our
461  * service thread.
462  */
463 void
464 my_service_queue(void *arg)
465 {
466         lwkt_msg_t msg;
467
468         msg = kmalloc(sizeof(*msg), M_TEMP, M_WAITOK);
469
470         /* Set reply port to autofree. */
471         lwkt_initmsg(msg, &my_autofree_rport, 0);
472
473         /* Attach the argument to the message. */
474         msg->u.ms_resultp = arg;
475
476         /* Send it. */
477         lwkt_sendmsg(my_service_port, msg);
478 }
479
480 /*
481  * This is the routine executed by our service thread.
482  */
483 static void
484 my_service_loop(void *dummy __unused)
485 {
486         lwkt_msg_t msg;
487         thread_t td = curthread;
488
489         while ((msg = lwkt_waitport(&td->td_msgport, 0)) != NULL) {
490                 /*
491                  * Do some work in the receiver thread context.  In this
492                  * example, the sender wrote his name in the argument he
493                  * sent us.  We print it here.
494                  */
495                 char *arg = msg->u.ms_resultp;
496                 kprintf("%s: Hi %s! Got your msg.\en", curthread->td_comm, arg);
497
498                 /* And finally reply to the message. */
499                 lwkt_replymsg(msg, 0);
500         }
501 }
502
503 static void
504 my_autofree_reply(lwkt_port_t port, lwkt_msg_t msg)
505 {
506         kfree(msg->u.ms_resultp, M_TEMP);
507         kfree(msg, M_TEMP);
508 }
509
510 static void
511 my_service_init(void)
512 {
513         thread_t tdp;
514
515         /* Initialize our auto free reply port. */
516         lwkt_initport_replyonly(&my_autofree_rport, my_autofree_reply);
517
518         /* Create our service thread on CPU 0. */
519         lwkt_create(my_service_loop, NULL, &tdp, NULL, 0, 0, "myservice");
520         my_service_port = &tdp->td_msgport;
521 }
522
523 /*
524  * Example use case. Initialize the service and send the current thread name
525  * to the service thread.
526  */
527 static void
528 mod_load(void)
529 {
530         void *arg;
531         int len;
532
533         my_service_init();
534         len = strlen(curthread->td_comm);
535         arg = kmalloc(len + 1, M_TEMP, M_WAITOK);
536         bcopy(curthread->td_comm, arg, len + 1);
537         kprintf("%s: Sending message.\en", curthread->td_comm);
538         my_service_queue(arg);
539 }
540 .Ed
541 .Sh NOTES
542 All the default putport handlers (used when a message is sent) currently
543 implement asynchronous putports only, i.e.  all *_putport() handlers return
544 .Er EASYNC .
545 You can still have synchronous putport handlers (which are run in the sender's
546 context) but you have to implement the function yourself and then override the
547 default.
548 .Pp
549 Port handler functions can be overridden with custom functions if required.
550 You can override the default putport handler by either using the
551 .Fn lwkt_initport_putonly
552 initializer, or by manipulating the mp_putport handler pointer directly on the
553 lwkt_port structure.
554 .Pp
555 There is one such case where the putport handler is overridden in
556 .Pa sys/kern/netisr.c.
557 In that case, the putport handler is overridden to detect a loopback message
558 (when the target port belongs to the sending thread).
559 This special putport handler turns the sent message into a direct function call
560 instead of queueing it to the port.
561 .Pp
562 The
563 .Fn lwkt_replymsg
564 function works differently depending on the original message request.  If the
565 message was originally an asynchronous request, the reply will be queued to the
566 sender's reply port. If the message was originally a synchronous request, then
567 this function will just write the error response on the message and wake up the
568 waiter without queueing the message to the reply port.
569 There is no need to queue in the synchronous request case because the original
570 sender had blocked waiting on this specific message with
571 .Fn lwkt_domsg .
572 .Pp
573 As is the case with putport handler, the replyport handler can also be
574 overridden.
575 You override the default replyport handler by using the
576 .Fn lwkt_initport_replyonly
577 or the
578 .Fn lwkt_initport_replyonly_null
579 port initializers, or by manipulating the mp_replyport handler pointer directly
580 on the lwkt_port structure.
581 .Pp
582 The sent message structure is reused for replies.
583 When a message is replied to, the error response is written on the message
584 which is subsequently sent to the reply port.
585 .Sh SEE ALSO
586 .Xr serializer 9 ,
587 .Xr spinlock 9
588 .Sh HISTORY
589 The LWKT msgport interface first appeared in
590 .Dx 1.0 .
591 .Sh AUTHORS
592 .An -nosplit
593 The
594 .Nm msgport
595 message passing interface implementation was written by
596 .An Matthew Dillon .
597 This manual page was written by
598 .An Nuno Antunes .