1 /* 2 * Copyright (c) 2003, 2004 Jeffrey M. Hsu. All rights reserved. 3 * Copyright (c) 2003, 2004 The DragonFly Project. All rights reserved. 4 * 5 * This code is derived from software contributed to The DragonFly Project 6 * by Jeffrey M. Hsu. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 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 the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of The DragonFly Project nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific, prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * $DragonFly: src/sys/kern/uipc_msg.c,v 1.21 2008/06/17 20:50:11 aggelos Exp $ 34 */ 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/kernel.h> 39 #include <sys/msgport.h> 40 #include <sys/protosw.h> 41 #include <sys/socket.h> 42 #include <sys/socketvar.h> 43 #include <sys/socketops.h> 44 #include <sys/thread.h> 45 #include <sys/thread2.h> 46 #include <sys/msgport2.h> 47 #include <net/netmsg2.h> 48 49 #include <net/netisr.h> 50 #include <net/netmsg.h> 51 52 int 53 so_pru_abort(struct socket *so) 54 { 55 int error; 56 struct netmsg_pru_abort msg; 57 lwkt_port_t port; 58 59 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_ABORT); 60 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 61 netmsg_pru_abort); 62 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_abort; 63 msg.nm_so = so; 64 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 65 return (error); 66 } 67 68 int 69 so_pru_accept(struct socket *so, struct sockaddr **nam) 70 { 71 /* Block (memory allocation) in process context. XXX JH */ 72 return ((*so->so_proto->pr_usrreqs->pru_accept)(so, nam)); 73 74 #ifdef notdef 75 int error; 76 struct netmsg_pru_accept msg; 77 lwkt_port_t port; 78 79 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_ACCEPT); 80 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 81 netmsg_pru_accept); 82 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_accept; 83 msg.nm_so = so; 84 msg.nm_nam = nam; 85 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 86 return (error); 87 #endif 88 } 89 90 int 91 so_pru_attach(struct socket *so, int proto, struct pru_attach_info *ai) 92 { 93 int error; 94 struct netmsg_pru_attach msg; 95 lwkt_port_t port; 96 97 port = so->so_proto->pr_mport(NULL, NULL, NULL, PRU_ATTACH); 98 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 99 netmsg_pru_attach); 100 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_attach; 101 msg.nm_so = so; 102 msg.nm_proto = proto; 103 msg.nm_ai = ai; 104 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 105 return (error); 106 } 107 108 int 109 so_pru_bind(struct socket *so, struct sockaddr *nam, struct thread *td) 110 { 111 int error; 112 struct netmsg_pru_bind msg; 113 lwkt_port_t port; 114 115 /* Send mesg to thread for new address. */ 116 port = so->so_proto->pr_mport(NULL, nam, NULL, PRU_BIND); 117 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 118 netmsg_pru_bind); 119 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_bind; 120 msg.nm_so = so; 121 msg.nm_nam = nam; 122 msg.nm_td = td; /* used only for prison_ip() XXX JH */ 123 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 124 return (error); 125 } 126 127 int 128 so_pru_connect(struct socket *so, struct sockaddr *nam, struct thread *td) 129 { 130 int error; 131 struct netmsg_pru_connect msg; 132 lwkt_port_t port; 133 134 port = so->so_proto->pr_mport(so, nam, NULL, PRU_CONNECT); 135 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 136 netmsg_pru_connect); 137 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_connect; 138 msg.nm_so = so; 139 msg.nm_nam = nam; 140 msg.nm_td = td; 141 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 142 return (error); 143 } 144 145 int 146 so_pru_connect2(struct socket *so1, struct socket *so2) 147 { 148 int error; 149 struct netmsg_pru_connect2 msg; 150 lwkt_port_t port; 151 152 port = so1->so_proto->pr_mport(so1, NULL, NULL, PRU_CONNECT2); 153 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 154 netmsg_pru_connect2); 155 msg.nm_prufn = so1->so_proto->pr_usrreqs->pru_connect2; 156 msg.nm_so1 = so1; 157 msg.nm_so2 = so2; 158 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 159 return (error); 160 } 161 162 int 163 so_pru_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp) 164 { 165 return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, ifp, 166 curthread)); 167 #ifdef gag /* does copyin and copyout deep inside stack XXX JH */ 168 int error; 169 struct netmsg_pru_control msg; 170 lwkt_port_t port; 171 172 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_CONTROL); 173 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 174 netmsg_pru_control); 175 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_control; 176 msg.nm_so = so; 177 msg.nm_cmd = cmd; 178 msg.nm_data = data; 179 msg.nm_ifp = ifp; 180 msg.nm_td = td; 181 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 182 return (error); 183 #endif 184 } 185 186 int 187 so_pru_detach(struct socket *so) 188 { 189 int error; 190 struct netmsg_pru_detach msg; 191 lwkt_port_t port; 192 193 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_DETACH); 194 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 195 netmsg_pru_detach); 196 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_detach; 197 msg.nm_so = so; 198 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 199 return (error); 200 } 201 202 int 203 so_pru_disconnect(struct socket *so) 204 { 205 int error; 206 struct netmsg_pru_disconnect msg; 207 lwkt_port_t port; 208 209 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_DISCONNECT); 210 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 211 netmsg_pru_disconnect); 212 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_disconnect; 213 msg.nm_so = so; 214 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 215 return (error); 216 } 217 218 int 219 so_pru_listen(struct socket *so, struct thread *td) 220 { 221 int error; 222 struct netmsg_pru_listen msg; 223 lwkt_port_t port; 224 225 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_LISTEN); 226 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 227 netmsg_pru_listen); 228 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_listen; 229 msg.nm_so = so; 230 msg.nm_td = td; /* used only for prison_ip() XXX JH */ 231 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 232 return (error); 233 } 234 235 int 236 so_pru_peeraddr(struct socket *so, struct sockaddr **nam) 237 { 238 int error; 239 struct netmsg_pru_peeraddr msg; 240 lwkt_port_t port; 241 242 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_PEERADDR); 243 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 244 netmsg_pru_peeraddr); 245 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_peeraddr; 246 msg.nm_so = so; 247 msg.nm_nam = nam; 248 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 249 return (error); 250 } 251 252 int 253 so_pru_rcvd(struct socket *so, int flags) 254 { 255 int error; 256 struct netmsg_pru_rcvd msg; 257 lwkt_port_t port; 258 259 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_RCVD); 260 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 261 netmsg_pru_rcvd); 262 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvd; 263 msg.nm_so = so; 264 msg.nm_flags = flags; 265 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 266 return (error); 267 } 268 269 int 270 so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags) 271 { 272 int error; 273 struct netmsg_pru_rcvoob msg; 274 lwkt_port_t port; 275 276 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_RCVOOB); 277 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 278 netmsg_pru_rcvoob); 279 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvoob; 280 msg.nm_so = so; 281 msg.nm_m = m; 282 msg.nm_flags = flags; 283 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 284 return (error); 285 } 286 287 int 288 so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 289 struct mbuf *control, struct thread *td) 290 { 291 int error; 292 struct netmsg_pru_send msg; 293 lwkt_port_t port; 294 295 port = so->so_proto->pr_mport(so, addr, &m, PRU_SEND); 296 if (port == NULL) { 297 KKASSERT(m == NULL); 298 return EINVAL; 299 } 300 301 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 302 netmsg_pru_send); 303 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_send; 304 msg.nm_so = so; 305 msg.nm_flags = flags; 306 msg.nm_m = m; 307 msg.nm_addr = addr; 308 msg.nm_control = control; 309 msg.nm_td = td; 310 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 311 return (error); 312 } 313 314 int 315 so_pru_sense(struct socket *so, struct stat *sb) 316 { 317 int error; 318 struct netmsg_pru_sense msg; 319 lwkt_port_t port; 320 321 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SENSE); 322 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 323 netmsg_pru_sense); 324 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sense; 325 msg.nm_so = so; 326 msg.nm_stat = sb; 327 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 328 return (error); 329 } 330 331 int 332 so_pru_shutdown(struct socket *so) 333 { 334 int error; 335 struct netmsg_pru_shutdown msg; 336 lwkt_port_t port; 337 338 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SHUTDOWN); 339 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 340 netmsg_pru_shutdown); 341 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_shutdown; 342 msg.nm_so = so; 343 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 344 return (error); 345 } 346 347 int 348 so_pru_sockaddr(struct socket *so, struct sockaddr **nam) 349 { 350 int error; 351 struct netmsg_pru_sockaddr msg; 352 lwkt_port_t port; 353 354 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SOCKADDR); 355 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 356 netmsg_pru_sockaddr); 357 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sockaddr; 358 msg.nm_so = so; 359 msg.nm_nam = nam; 360 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 361 return (error); 362 } 363 364 int 365 so_pru_sopoll(struct socket *so, int events, struct ucred *cred) 366 { 367 int error; 368 struct netmsg_pru_sopoll msg; 369 lwkt_port_t port; 370 371 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_SOPOLL); 372 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 373 netmsg_pru_sopoll); 374 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sopoll; 375 msg.nm_so = so; 376 msg.nm_events = events; 377 msg.nm_cred = cred; 378 msg.nm_td = curthread; 379 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 380 return (error); 381 } 382 383 int 384 so_pru_ctloutput(struct socket *so, struct sockopt *sopt) 385 { 386 struct netmsg_pru_ctloutput msg; 387 lwkt_port_t port; 388 int error; 389 void *uval = NULL; 390 int need_copy; 391 392 need_copy = sopt->sopt_td != NULL; 393 if (need_copy) { 394 uval = sopt->sopt_val; 395 /* 396 * we keep duplicate copies, but for option {s,g}etting 397 * who cares? 398 */ 399 sopt->sopt_val = kmalloc(sopt->sopt_valsize, M_TEMP, M_WAITOK); 400 error = copyin(uval, sopt->sopt_val, sopt->sopt_valsize); 401 if (error) 402 goto out; 403 } 404 port = so->so_proto->pr_mport(so, NULL, NULL, PRU_CTLOUTPUT); 405 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 406 netmsg_pru_ctloutput); 407 /* TBD: move pr_ctloutput to pr_usrreqs */ 408 msg.nm_prufn = so->so_proto->pr_ctloutput; 409 msg.nm_so = so; 410 msg.nm_sopt = sopt; 411 error = lwkt_domsg(port, &msg.nm_netmsg.nm_lmsg, 0); 412 out: 413 if (need_copy) { 414 if (!error) { 415 error = copyout(sopt->sopt_val, uval, 416 sopt->sopt_valsize); 417 } 418 /* 419 * watch out: this may not be the same memory we allocated, 420 * callees "know" we're using M_TEMP so any reallocations 421 * will happen from there 422 */ 423 kfree(sopt->sopt_val, M_TEMP); 424 sopt->sopt_val = uval; 425 } 426 return (error); 427 } 428 429 /* 430 * If we convert all the protosw pr_ functions for all the protocols 431 * to take a message directly, this layer can go away. For the moment 432 * our dispatcher ignores the return value, but since we are handling 433 * the replymsg ourselves we return EASYNC by convention. 434 */ 435 void 436 netmsg_pru_abort(netmsg_t msg) 437 { 438 struct netmsg_pru_abort *nm = (void *)msg; 439 440 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so)); 441 } 442 443 #ifdef notused 444 void 445 netmsg_pru_accept(netmsg_t msg) 446 { 447 struct netmsg_pru_accept *nm = (void *)msg; 448 449 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_nam)); 450 } 451 #endif 452 453 void 454 netmsg_pru_attach(netmsg_t msg) 455 { 456 struct netmsg_pru_attach *nm = (void *)msg; 457 458 lwkt_replymsg(&msg->nm_lmsg, 459 nm->nm_prufn(nm->nm_so, nm->nm_proto, nm->nm_ai)); 460 } 461 462 void 463 netmsg_pru_bind(netmsg_t msg) 464 { 465 struct netmsg_pru_bind *nm = (void *)msg; 466 467 lwkt_replymsg(&msg->nm_lmsg, 468 nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td)); 469 } 470 471 void 472 netmsg_pru_connect(netmsg_t msg) 473 { 474 struct netmsg_pru_connect *nm = (void *)msg; 475 476 lwkt_replymsg(&msg->nm_lmsg, 477 nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td)); 478 } 479 480 void 481 netmsg_pru_connect2(netmsg_t msg) 482 { 483 struct netmsg_pru_connect2 *nm = (void *)msg; 484 485 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so1, nm->nm_so2)); 486 } 487 488 void 489 netmsg_pru_control(netmsg_t msg) 490 { 491 struct netmsg_pru_control *nm = (void *)msg; 492 int error; 493 494 error = nm->nm_prufn(nm->nm_so, nm->nm_cmd, nm->nm_data, 495 nm->nm_ifp, nm->nm_td); 496 lwkt_replymsg(&msg->nm_lmsg, error); 497 } 498 499 void 500 netmsg_pru_detach(netmsg_t msg) 501 { 502 struct netmsg_pru_detach *nm = (void *)msg; 503 504 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so)); 505 } 506 507 void 508 netmsg_pru_disconnect(netmsg_t msg) 509 { 510 struct netmsg_pru_disconnect *nm = (void *)msg; 511 512 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so)); 513 } 514 515 void 516 netmsg_pru_listen(netmsg_t msg) 517 { 518 struct netmsg_pru_listen *nm = (void *)msg; 519 520 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_td)); 521 } 522 523 void 524 netmsg_pru_peeraddr(netmsg_t msg) 525 { 526 struct netmsg_pru_peeraddr *nm = (void *)msg; 527 528 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_nam)); 529 } 530 531 void 532 netmsg_pru_rcvd(netmsg_t msg) 533 { 534 struct netmsg_pru_rcvd *nm = (void *)msg; 535 536 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_flags)); 537 } 538 539 void 540 netmsg_pru_rcvoob(netmsg_t msg) 541 { 542 struct netmsg_pru_rcvoob *nm = (void *)msg; 543 544 lwkt_replymsg(&msg->nm_lmsg, 545 nm->nm_prufn(nm->nm_so, nm->nm_m, nm->nm_flags)); 546 } 547 548 void 549 netmsg_pru_send(netmsg_t msg) 550 { 551 struct netmsg_pru_send *nm = (void *)msg; 552 int error; 553 554 error = nm->nm_prufn(nm->nm_so, nm->nm_flags, nm->nm_m, 555 nm->nm_addr, nm->nm_control, nm->nm_td); 556 lwkt_replymsg(&msg->nm_lmsg, error); 557 } 558 559 void 560 netmsg_pru_sense(netmsg_t msg) 561 { 562 struct netmsg_pru_sense *nm = (void *)msg; 563 564 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_stat)); 565 } 566 567 void 568 netmsg_pru_shutdown(netmsg_t msg) 569 { 570 struct netmsg_pru_shutdown *nm = (void *)msg; 571 572 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so)); 573 } 574 575 void 576 netmsg_pru_sockaddr(netmsg_t msg) 577 { 578 struct netmsg_pru_sockaddr *nm = (void *)msg; 579 580 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_nam)); 581 } 582 583 void 584 netmsg_pru_sopoll(netmsg_t msg) 585 { 586 struct netmsg_pru_sopoll *nm = (void *)msg; 587 int error; 588 589 error = nm->nm_prufn(nm->nm_so, nm->nm_events, nm->nm_cred, nm->nm_td); 590 lwkt_replymsg(&msg->nm_lmsg, error); 591 } 592 593 void 594 netmsg_pru_ctloutput(netmsg_t msg) 595 { 596 struct netmsg_pru_ctloutput *nm = (void *)msg; 597 598 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prufn(nm->nm_so, nm->nm_sopt)); 599 } 600 601 void 602 netmsg_pr_timeout(netmsg_t msg) 603 { 604 struct netmsg_pr_timeout *nm = (void *)msg; 605 606 lwkt_replymsg(&msg->nm_lmsg, nm->nm_prfn()); 607 } 608 609 /* 610 * Handle a predicate event request. This function is only called once 611 * when the predicate message queueing request is received. 612 */ 613 void 614 netmsg_so_notify(netmsg_t netmsg) 615 { 616 struct netmsg_so_notify *msg = (void *)netmsg; 617 struct signalsockbuf *ssb; 618 619 ssb = (msg->nm_etype & NM_REVENT) ? 620 &msg->nm_so->so_rcv : 621 &msg->nm_so->so_snd; 622 623 /* 624 * Reply immediately if the event has occured, otherwise queue the 625 * request. 626 */ 627 if (msg->nm_predicate(&msg->nm_netmsg)) { 628 lwkt_replymsg(&msg->nm_netmsg.nm_lmsg, 629 msg->nm_netmsg.nm_lmsg.ms_error); 630 } else { 631 TAILQ_INSERT_TAIL(&ssb->ssb_sel.si_mlist, msg, nm_list); 632 ssb->ssb_flags |= SSB_MEVENT; 633 } 634 } 635 636 /* 637 * Called by doio when trying to abort a netmsg_so_notify message. 638 * Unlike the other functions this one is dispatched directly by 639 * the LWKT subsystem, so it takes a lwkt_msg_t as an argument. 640 * 641 * The original message, lmsg, is under the control of the caller and 642 * will not be destroyed until we return so we can safely reference it 643 * in our synchronous abort request. 644 * 645 * This part of the abort request occurs on the originating cpu which 646 * means we may race the message flags and the original message may 647 * not even have been processed by the target cpu yet. 648 */ 649 void 650 netmsg_so_notify_doabort(lwkt_msg_t lmsg) 651 { 652 struct netmsg_so_notify_abort msg; 653 654 if ((lmsg->ms_flags & (MSGF_DONE | MSGF_REPLY)) == 0) { 655 netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0, 656 netmsg_so_notify_abort); 657 msg.nm_notifymsg = (void *)lmsg; 658 lwkt_domsg(lmsg->ms_target_port, &msg.nm_netmsg.nm_lmsg, 0); 659 } 660 } 661 662 /* 663 * Predicate requests can be aborted. This function is only called once 664 * and will interlock against processing/reply races (since such races 665 * occur on the same thread that controls the port where the abort is 666 * requeued). 667 * 668 * This part of the abort request occurs on the target cpu. The message 669 * flags must be tested again in case the test that we did on the 670 * originating cpu raced. Since messages are handled in sequence, the 671 * original message will have already been handled by the loop and either 672 * replied to or queued. 673 * 674 * We really only need to interlock with MSGF_REPLY (a bit that is set on 675 * our cpu when we reply). Note that MSGF_DONE is not set until the 676 * reply reaches the originating cpu. Test both bits anyway. 677 */ 678 void 679 netmsg_so_notify_abort(netmsg_t netmsg) 680 { 681 struct netmsg_so_notify_abort *abrtmsg = (void *)netmsg; 682 struct netmsg_so_notify *msg = abrtmsg->nm_notifymsg; 683 struct signalsockbuf *ssb; 684 685 /* 686 * The original notify message is not destroyed until after the 687 * abort request is returned, so we can check its state. 688 */ 689 if ((msg->nm_netmsg.nm_lmsg.ms_flags & (MSGF_DONE | MSGF_REPLY)) == 0) { 690 ssb = (msg->nm_etype & NM_REVENT) ? 691 &msg->nm_so->so_rcv : 692 &msg->nm_so->so_snd; 693 TAILQ_REMOVE(&ssb->ssb_sel.si_mlist, msg, nm_list); 694 lwkt_replymsg(&msg->nm_netmsg.nm_lmsg, EINTR); 695 } 696 697 /* 698 * Reply to the abort message 699 */ 700 lwkt_replymsg(&abrtmsg->nm_netmsg.nm_lmsg, 0); 701 } 702 703