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