1 /* 2 * Copyright (c) 2003, 2004 Matthew Dillon. All rights reserved. 3 * Copyright (c) 2003, 2004 Jeffrey M. Hsu. All rights reserved. 4 * Copyright (c) 2003 Jonathan Lemon. All rights reserved. 5 * Copyright (c) 2003, 2004 The DragonFly Project. All rights reserved. 6 * 7 * This code is derived from software contributed to The DragonFly Project 8 * by Jonathan Lemon, Jeffrey M. Hsu, and Matthew Dillon. 9 * 10 * Jonathan Lemon gave Jeffrey Hsu permission to combine his copyright 11 * into this one around July 8 2004. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. Neither the name of The DragonFly Project nor the names of its 22 * contributors may be used to endorse or promote products derived 23 * from this software without specific, prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 28 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 29 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 30 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 31 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 33 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 34 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 35 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * $DragonFly: src/sys/net/netisr.c,v 1.21 2004/07/18 16:26:41 dillon Exp $ 39 */ 40 41 /* 42 * Copyright (c) 2003, 2004 Jeffrey M. Hsu. All rights reserved. 43 * 44 * License terms: all terms for the DragonFly license above plus the following: 45 * 46 * 4. All advertising materials mentioning features or use of this software 47 * must display the following acknowledgement: 48 * 49 * This product includes software developed by Jeffrey M. Hsu 50 * for the DragonFly Project. 51 * 52 * This requirement may be waived with permission from Jeffrey Hsu. 53 * This requirement will sunset and may be removed on July 8 2005, 54 * after which the standard DragonFly license (as shown above) will 55 * apply. 56 */ 57 58 #include <sys/param.h> 59 #include <sys/systm.h> 60 #include <sys/kernel.h> 61 #include <sys/malloc.h> 62 #include <sys/msgport.h> 63 #include <sys/proc.h> 64 #include <sys/interrupt.h> 65 #include <sys/socket.h> 66 #include <sys/sysctl.h> 67 #include <net/if.h> 68 #include <net/if_var.h> 69 #include <net/netisr.h> 70 #include <machine/cpufunc.h> 71 #include <machine/ipl.h> 72 73 #include <sys/thread2.h> 74 #include <sys/msgport2.h> 75 76 static struct netisr netisrs[NETISR_MAX]; 77 78 /* Per-CPU thread to handle any protocol. */ 79 struct thread netisr_cpu[MAXCPU]; 80 lwkt_port netisr_afree_rport; 81 lwkt_port netisr_adone_rport; 82 lwkt_port netisr_sync_port; 83 84 /* 85 * netisr_afree_rport replymsg function, only used to handle async 86 * messages which the sender has abandoned to their fate. 87 */ 88 static void 89 netisr_autofree_reply(lwkt_port_t port, lwkt_msg_t msg) 90 { 91 free(msg, M_LWKTMSG); 92 } 93 94 static void 95 netisr_autodone_reply(lwkt_port_t port, lwkt_msg_t msg) 96 { 97 crit_enter(); 98 msg->ms_flags |= MSGF_DONE|MSGF_REPLY1; 99 crit_exit(); 100 } 101 102 /* 103 * We must construct a custom putport function (which runs in the context 104 * of the message originator) 105 * 106 * Our custom putport must check for self-referential messages, which can 107 * occur when the so_upcall routine is called (e.g. nfs). Self referential 108 * messages are executed synchronously. However, we must panic if the message 109 * is not marked DONE on completion because the self-referential case cannot 110 * block without deadlocking. 111 * 112 * note: ms_target_port does not need to be set when returning a synchronous 113 * error code. 114 */ 115 int 116 netmsg_put_port(lwkt_port_t port, lwkt_msg_t lmsg) 117 { 118 int error; 119 120 if ((lmsg->ms_flags & MSGF_ASYNC) == 0 && port->mp_td == curthread) { 121 error = lmsg->ms_cmd.cm_func(lmsg); 122 if (error == EASYNC && (lmsg->ms_flags & MSGF_DONE) == 0) 123 panic("netmsg_put_port: self-referential deadlock on netport"); 124 return(error); 125 } else { 126 return(lwkt_default_putport(port, lmsg)); 127 } 128 } 129 130 /* 131 * UNIX DOMAIN sockets still have to run their uipc functions synchronously, 132 * because they depend on the user proc context for a number of things 133 * (like creds) which we have not yet incorporated into the message structure. 134 * 135 * However, we maintain or message/port abstraction. Having a special 136 * synchronous port which runs the commands synchronously gives us the 137 * ability to serialize operations in one place later on when we start 138 * removing the BGL. 139 * 140 * We clear MSGF_DONE prior to executing the message in order to close 141 * any potential replymsg races with the flags field. If a synchronous 142 * result code is returned we set MSGF_DONE again. MSGF_DONE's flag state 143 * must be correct or the caller will be confused. 144 */ 145 static int 146 netmsg_sync_putport(lwkt_port_t port, lwkt_msg_t lmsg) 147 { 148 int error; 149 150 lmsg->ms_flags &= ~MSGF_DONE; 151 lmsg->ms_target_port = port; /* required for abort */ 152 error = lmsg->ms_cmd.cm_func(lmsg); 153 if (error == EASYNC) 154 error = lwkt_waitmsg(lmsg); 155 else 156 lmsg->ms_flags |= MSGF_DONE; 157 return(error); 158 } 159 160 static void 161 netmsg_sync_abortport(lwkt_port_t port, lwkt_msg_t lmsg) 162 { 163 lmsg->ms_abort_port = lmsg->ms_reply_port; 164 lmsg->ms_flags |= MSGF_ABORTED; 165 lmsg->ms_abort.cm_func(lmsg); 166 } 167 168 static void 169 netisr_init(void) 170 { 171 int i; 172 173 /* 174 * Create default per-cpu threads for generic protocol handling. 175 */ 176 for (i = 0; i < ncpus; ++i) { 177 lwkt_create(netmsg_service_loop, NULL, NULL, &netisr_cpu[i], 0, i, 178 "netisr_cpu %d", i); 179 netisr_cpu[i].td_msgport.mp_putport = netmsg_put_port; 180 } 181 182 /* 183 * The netisr_afree_rport is a special reply port which automatically 184 * frees the replied message. The netisr_adone_rport() simply marks 185 * the message as being done. 186 */ 187 lwkt_initport(&netisr_afree_rport, NULL); 188 netisr_afree_rport.mp_replyport = netisr_autofree_reply; 189 lwkt_initport(&netisr_adone_rport, NULL); 190 netisr_adone_rport.mp_replyport = netisr_autodone_reply; 191 192 /* 193 * The netisr_syncport is a special port which executes the message 194 * synchronously and waits for it if EASYNC is returned. 195 */ 196 lwkt_initport(&netisr_sync_port, NULL); 197 netisr_sync_port.mp_putport = netmsg_sync_putport; 198 netisr_sync_port.mp_abortport = netmsg_sync_abortport; 199 } 200 201 SYSINIT(netisr, SI_SUB_PROTO_BEGIN, SI_ORDER_FIRST, netisr_init, NULL); 202 203 void 204 netmsg_service_loop(void *arg) 205 { 206 struct netmsg *msg; 207 208 while ((msg = lwkt_waitport(&curthread->td_msgport, NULL))) { 209 msg->nm_lmsg.ms_cmd.cm_func(&msg->nm_lmsg); 210 } 211 } 212 213 /* 214 * Call the netisr directly. 215 * Queueing may be done in the msg port layer at its discretion. 216 */ 217 void 218 netisr_dispatch(int num, struct mbuf *m) 219 { 220 /* just queue it for now XXX JH */ 221 netisr_queue(num, m); 222 } 223 224 /* 225 * Same as netisr_dispatch(), but always queue. 226 * This is either used in places where we are not confident that 227 * direct dispatch is possible, or where queueing is required. 228 */ 229 int 230 netisr_queue(int num, struct mbuf *m) 231 { 232 struct netisr *ni; 233 struct netmsg_packet *pmsg; 234 lwkt_port_t port; 235 236 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))), 237 ("netisr_queue: bad isr %d", num)); 238 239 ni = &netisrs[num]; 240 if (ni->ni_handler == NULL) { 241 printf("netisr_queue: unregistered isr %d\n", num); 242 return (EIO); 243 } 244 245 if ((port = ni->ni_mport(&m)) == NULL) 246 return (EIO); 247 248 /* use better message allocation system with limits later XXX JH */ 249 pmsg = malloc(sizeof(struct netmsg_packet), M_LWKTMSG, M_WAITOK); 250 251 lwkt_initmsg(&pmsg->nm_lmsg, &netisr_afree_rport, 0, 252 lwkt_cmd_func((void *)ni->ni_handler), lwkt_cmd_op_none); 253 pmsg->nm_packet = m; 254 pmsg->nm_lmsg.u.ms_result = num; 255 lwkt_sendmsg(port, &pmsg->nm_lmsg); 256 return (0); 257 } 258 259 void 260 netisr_register(int num, lwkt_portfn_t mportfn, netisr_fn_t handler) 261 { 262 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))), 263 ("netisr_register: bad isr %d", num)); 264 lwkt_initmsg(&netisrs[num].ni_netmsg.nm_lmsg, &netisr_adone_rport, 0, 265 lwkt_cmd_op_none, lwkt_cmd_op_none); 266 netisrs[num].ni_mport = mportfn; 267 netisrs[num].ni_handler = handler; 268 } 269 270 int 271 netisr_unregister(int num) 272 { 273 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))), 274 ("unregister_netisr: bad isr number: %d\n", num)); 275 276 /* XXX JH */ 277 return (0); 278 } 279 280 /* 281 * Return message port for default handler thread on CPU 0. 282 */ 283 lwkt_port_t 284 cpu0_portfn(struct mbuf **mptr) 285 { 286 return (&netisr_cpu[0].td_msgport); 287 } 288 289 /* ARGSUSED */ 290 lwkt_port_t 291 cpu0_soport(struct socket *so __unused, struct sockaddr *nam __unused, 292 int req __unused) 293 { 294 return (&netisr_cpu[0].td_msgport); 295 } 296 297 lwkt_port_t 298 sync_soport(struct socket *so __unused, struct sockaddr *nam __unused, 299 int req __unused) 300 { 301 return (&netisr_sync_port); 302 } 303 304 /* 305 * schednetisr() is used to call the netisr handler from the appropriate 306 * netisr thread for polling and other purposes. 307 * 308 * This function may be called from a hard interrupt or IPI and must be 309 * MP SAFE and non-blocking. We use a fixed per-cpu message instead of 310 * trying to allocate one. We must get ourselves onto the target cpu 311 * to safely check the MSGF_DONE bit on the message but since the message 312 * will be sent to that cpu anyway this does not add any extra work beyond 313 * what lwkt_sendmsg() would have already had to do to schedule the target 314 * thread. 315 */ 316 static void 317 schednetisr_remote(void *data) 318 { 319 int num = (int)data; 320 struct netisr *ni = &netisrs[num]; 321 lwkt_port_t port = &netisr_cpu[0].td_msgport; 322 struct netmsg *pmsg; 323 324 pmsg = &netisrs[num].ni_netmsg; 325 crit_enter(); 326 if (pmsg->nm_lmsg.ms_flags & MSGF_DONE) { 327 lwkt_initmsg(&pmsg->nm_lmsg, &netisr_adone_rport, 0, 328 lwkt_cmd_func((void *)ni->ni_handler), lwkt_cmd_op_none); 329 pmsg->nm_lmsg.u.ms_result = num; 330 lwkt_sendmsg(port, &pmsg->nm_lmsg); 331 } 332 crit_exit(); 333 } 334 335 void 336 schednetisr(int num) 337 { 338 KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))), 339 ("schednetisr: bad isr %d", num)); 340 #ifdef SMP 341 if (mycpu->gd_cpuid != 0) 342 lwkt_send_ipiq(globaldata_find(0), schednetisr_remote, (void *)num); 343 else 344 schednetisr_remote((void *)num); 345 #else 346 schednetisr_remote((void *)num); 347 #endif 348 } 349 350