1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* 3 * Copyright (c) 2015, Sony Mobile Communications Inc. 4 * Copyright (c) 2013, The Linux Foundation. All rights reserved. 5 * Copyright (c) 2020, Linaro Ltd. 6 */ 7 8 #include <linux/module.h> 9 #include <linux/qrtr.h> 10 #include <linux/workqueue.h> 11 #include <net/sock.h> 12 13 #include "qrtr.h" 14 15 #include <trace/events/sock.h> 16 #define CREATE_TRACE_POINTS 17 #include <trace/events/qrtr.h> 18 19 static DEFINE_XARRAY(nodes); 20 21 static struct { 22 struct socket *sock; 23 struct sockaddr_qrtr bcast_sq; 24 struct list_head lookups; 25 struct workqueue_struct *workqueue; 26 struct work_struct work; 27 int local_node; 28 } qrtr_ns; 29 30 static const char * const qrtr_ctrl_pkt_strings[] = { 31 [QRTR_TYPE_HELLO] = "hello", 32 [QRTR_TYPE_BYE] = "bye", 33 [QRTR_TYPE_NEW_SERVER] = "new-server", 34 [QRTR_TYPE_DEL_SERVER] = "del-server", 35 [QRTR_TYPE_DEL_CLIENT] = "del-client", 36 [QRTR_TYPE_RESUME_TX] = "resume-tx", 37 [QRTR_TYPE_EXIT] = "exit", 38 [QRTR_TYPE_PING] = "ping", 39 [QRTR_TYPE_NEW_LOOKUP] = "new-lookup", 40 [QRTR_TYPE_DEL_LOOKUP] = "del-lookup", 41 }; 42 43 struct qrtr_server_filter { 44 unsigned int service; 45 unsigned int instance; 46 unsigned int ifilter; 47 }; 48 49 struct qrtr_lookup { 50 unsigned int service; 51 unsigned int instance; 52 53 struct sockaddr_qrtr sq; 54 struct list_head li; 55 }; 56 57 struct qrtr_server { 58 unsigned int service; 59 unsigned int instance; 60 61 unsigned int node; 62 unsigned int port; 63 64 struct list_head qli; 65 }; 66 67 struct qrtr_node { 68 unsigned int id; 69 struct xarray servers; 70 }; 71 72 static struct qrtr_node *node_get(unsigned int node_id) 73 { 74 struct qrtr_node *node; 75 76 node = xa_load(&nodes, node_id); 77 if (node) 78 return node; 79 80 /* If node didn't exist, allocate and insert it to the tree */ 81 node = kzalloc(sizeof(*node), GFP_KERNEL); 82 if (!node) 83 return NULL; 84 85 node->id = node_id; 86 xa_init(&node->servers); 87 88 if (xa_store(&nodes, node_id, node, GFP_KERNEL)) { 89 kfree(node); 90 return NULL; 91 } 92 93 return node; 94 } 95 96 static int server_match(const struct qrtr_server *srv, 97 const struct qrtr_server_filter *f) 98 { 99 unsigned int ifilter = f->ifilter; 100 101 if (f->service != 0 && srv->service != f->service) 102 return 0; 103 if (!ifilter && f->instance) 104 ifilter = ~0; 105 106 return (srv->instance & ifilter) == f->instance; 107 } 108 109 static int service_announce_new(struct sockaddr_qrtr *dest, 110 struct qrtr_server *srv) 111 { 112 struct qrtr_ctrl_pkt pkt; 113 struct msghdr msg = { }; 114 struct kvec iv; 115 116 trace_qrtr_ns_service_announce_new(srv->service, srv->instance, 117 srv->node, srv->port); 118 119 iv.iov_base = &pkt; 120 iv.iov_len = sizeof(pkt); 121 122 memset(&pkt, 0, sizeof(pkt)); 123 pkt.cmd = cpu_to_le32(QRTR_TYPE_NEW_SERVER); 124 pkt.server.service = cpu_to_le32(srv->service); 125 pkt.server.instance = cpu_to_le32(srv->instance); 126 pkt.server.node = cpu_to_le32(srv->node); 127 pkt.server.port = cpu_to_le32(srv->port); 128 129 msg.msg_name = (struct sockaddr *)dest; 130 msg.msg_namelen = sizeof(*dest); 131 132 return kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt)); 133 } 134 135 static void service_announce_del(struct sockaddr_qrtr *dest, 136 struct qrtr_server *srv) 137 { 138 struct qrtr_ctrl_pkt pkt; 139 struct msghdr msg = { }; 140 struct kvec iv; 141 int ret; 142 143 trace_qrtr_ns_service_announce_del(srv->service, srv->instance, 144 srv->node, srv->port); 145 146 iv.iov_base = &pkt; 147 iv.iov_len = sizeof(pkt); 148 149 memset(&pkt, 0, sizeof(pkt)); 150 pkt.cmd = cpu_to_le32(QRTR_TYPE_DEL_SERVER); 151 pkt.server.service = cpu_to_le32(srv->service); 152 pkt.server.instance = cpu_to_le32(srv->instance); 153 pkt.server.node = cpu_to_le32(srv->node); 154 pkt.server.port = cpu_to_le32(srv->port); 155 156 msg.msg_name = (struct sockaddr *)dest; 157 msg.msg_namelen = sizeof(*dest); 158 159 ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt)); 160 if (ret < 0 && ret != -ENODEV) 161 pr_err("failed to announce del service\n"); 162 163 return; 164 } 165 166 static void lookup_notify(struct sockaddr_qrtr *to, struct qrtr_server *srv, 167 bool new) 168 { 169 struct qrtr_ctrl_pkt pkt; 170 struct msghdr msg = { }; 171 struct kvec iv; 172 int ret; 173 174 iv.iov_base = &pkt; 175 iv.iov_len = sizeof(pkt); 176 177 memset(&pkt, 0, sizeof(pkt)); 178 pkt.cmd = new ? cpu_to_le32(QRTR_TYPE_NEW_SERVER) : 179 cpu_to_le32(QRTR_TYPE_DEL_SERVER); 180 if (srv) { 181 pkt.server.service = cpu_to_le32(srv->service); 182 pkt.server.instance = cpu_to_le32(srv->instance); 183 pkt.server.node = cpu_to_le32(srv->node); 184 pkt.server.port = cpu_to_le32(srv->port); 185 } 186 187 msg.msg_name = (struct sockaddr *)to; 188 msg.msg_namelen = sizeof(*to); 189 190 ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt)); 191 if (ret < 0 && ret != -ENODEV) 192 pr_err("failed to send lookup notification\n"); 193 } 194 195 static int announce_servers(struct sockaddr_qrtr *sq) 196 { 197 struct qrtr_server *srv; 198 struct qrtr_node *node; 199 unsigned long index; 200 int ret; 201 202 node = node_get(qrtr_ns.local_node); 203 if (!node) 204 return 0; 205 206 /* Announce the list of servers registered in this node */ 207 xa_for_each(&node->servers, index, srv) { 208 ret = service_announce_new(sq, srv); 209 if (ret < 0) { 210 if (ret == -ENODEV) 211 continue; 212 213 pr_err("failed to announce new service\n"); 214 return ret; 215 } 216 } 217 return 0; 218 } 219 220 static struct qrtr_server *server_add(unsigned int service, 221 unsigned int instance, 222 unsigned int node_id, 223 unsigned int port) 224 { 225 struct qrtr_server *srv; 226 struct qrtr_server *old; 227 struct qrtr_node *node; 228 229 if (!service || !port) 230 return NULL; 231 232 srv = kzalloc(sizeof(*srv), GFP_KERNEL); 233 if (!srv) 234 return NULL; 235 236 srv->service = service; 237 srv->instance = instance; 238 srv->node = node_id; 239 srv->port = port; 240 241 node = node_get(node_id); 242 if (!node) 243 goto err; 244 245 /* Delete the old server on the same port */ 246 old = xa_store(&node->servers, port, srv, GFP_KERNEL); 247 if (old) { 248 if (xa_is_err(old)) { 249 pr_err("failed to add server [0x%x:0x%x] ret:%d\n", 250 srv->service, srv->instance, xa_err(old)); 251 goto err; 252 } else { 253 kfree(old); 254 } 255 } 256 257 trace_qrtr_ns_server_add(srv->service, srv->instance, 258 srv->node, srv->port); 259 260 return srv; 261 262 err: 263 kfree(srv); 264 return NULL; 265 } 266 267 static int server_del(struct qrtr_node *node, unsigned int port, bool bcast) 268 { 269 struct qrtr_lookup *lookup; 270 struct qrtr_server *srv; 271 struct list_head *li; 272 273 srv = xa_load(&node->servers, port); 274 if (!srv) 275 return -ENOENT; 276 277 xa_erase(&node->servers, port); 278 279 /* Broadcast the removal of local servers */ 280 if (srv->node == qrtr_ns.local_node && bcast) 281 service_announce_del(&qrtr_ns.bcast_sq, srv); 282 283 /* Announce the service's disappearance to observers */ 284 list_for_each(li, &qrtr_ns.lookups) { 285 lookup = container_of(li, struct qrtr_lookup, li); 286 if (lookup->service && lookup->service != srv->service) 287 continue; 288 if (lookup->instance && lookup->instance != srv->instance) 289 continue; 290 291 lookup_notify(&lookup->sq, srv, false); 292 } 293 294 kfree(srv); 295 296 return 0; 297 } 298 299 static int say_hello(struct sockaddr_qrtr *dest) 300 { 301 struct qrtr_ctrl_pkt pkt; 302 struct msghdr msg = { }; 303 struct kvec iv; 304 int ret; 305 306 iv.iov_base = &pkt; 307 iv.iov_len = sizeof(pkt); 308 309 memset(&pkt, 0, sizeof(pkt)); 310 pkt.cmd = cpu_to_le32(QRTR_TYPE_HELLO); 311 312 msg.msg_name = (struct sockaddr *)dest; 313 msg.msg_namelen = sizeof(*dest); 314 315 ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt)); 316 if (ret < 0) 317 pr_err("failed to send hello msg\n"); 318 319 return ret; 320 } 321 322 /* Announce the list of servers registered on the local node */ 323 static int ctrl_cmd_hello(struct sockaddr_qrtr *sq) 324 { 325 int ret; 326 327 ret = say_hello(sq); 328 if (ret < 0) 329 return ret; 330 331 return announce_servers(sq); 332 } 333 334 static int ctrl_cmd_bye(struct sockaddr_qrtr *from) 335 { 336 struct qrtr_node *local_node; 337 struct qrtr_ctrl_pkt pkt; 338 struct qrtr_server *srv; 339 struct sockaddr_qrtr sq; 340 struct msghdr msg = { }; 341 struct qrtr_node *node; 342 unsigned long index; 343 struct kvec iv; 344 int ret; 345 346 iv.iov_base = &pkt; 347 iv.iov_len = sizeof(pkt); 348 349 node = node_get(from->sq_node); 350 if (!node) 351 return 0; 352 353 /* Advertise removal of this client to all servers of remote node */ 354 xa_for_each(&node->servers, index, srv) 355 server_del(node, srv->port, true); 356 357 /* Advertise the removal of this client to all local servers */ 358 local_node = node_get(qrtr_ns.local_node); 359 if (!local_node) 360 return 0; 361 362 memset(&pkt, 0, sizeof(pkt)); 363 pkt.cmd = cpu_to_le32(QRTR_TYPE_BYE); 364 pkt.client.node = cpu_to_le32(from->sq_node); 365 366 xa_for_each(&local_node->servers, index, srv) { 367 sq.sq_family = AF_QIPCRTR; 368 sq.sq_node = srv->node; 369 sq.sq_port = srv->port; 370 371 msg.msg_name = (struct sockaddr *)&sq; 372 msg.msg_namelen = sizeof(sq); 373 374 ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt)); 375 if (ret < 0 && ret != -ENODEV) { 376 pr_err("failed to send bye cmd\n"); 377 return ret; 378 } 379 } 380 return 0; 381 } 382 383 static int ctrl_cmd_del_client(struct sockaddr_qrtr *from, 384 unsigned int node_id, unsigned int port) 385 { 386 struct qrtr_node *local_node; 387 struct qrtr_lookup *lookup; 388 struct qrtr_ctrl_pkt pkt; 389 struct msghdr msg = { }; 390 struct qrtr_server *srv; 391 struct sockaddr_qrtr sq; 392 struct qrtr_node *node; 393 struct list_head *tmp; 394 struct list_head *li; 395 unsigned long index; 396 struct kvec iv; 397 int ret; 398 399 iv.iov_base = &pkt; 400 iv.iov_len = sizeof(pkt); 401 402 /* Don't accept spoofed messages */ 403 if (from->sq_node != node_id) 404 return -EINVAL; 405 406 /* Local DEL_CLIENT messages comes from the port being closed */ 407 if (from->sq_node == qrtr_ns.local_node && from->sq_port != port) 408 return -EINVAL; 409 410 /* Remove any lookups by this client */ 411 list_for_each_safe(li, tmp, &qrtr_ns.lookups) { 412 lookup = container_of(li, struct qrtr_lookup, li); 413 if (lookup->sq.sq_node != node_id) 414 continue; 415 if (lookup->sq.sq_port != port) 416 continue; 417 418 list_del(&lookup->li); 419 kfree(lookup); 420 } 421 422 /* Remove the server belonging to this port but don't broadcast 423 * DEL_SERVER. Neighbours would've already removed the server belonging 424 * to this port due to the DEL_CLIENT broadcast from qrtr_port_remove(). 425 */ 426 node = node_get(node_id); 427 if (node) 428 server_del(node, port, false); 429 430 /* Advertise the removal of this client to all local servers */ 431 local_node = node_get(qrtr_ns.local_node); 432 if (!local_node) 433 return 0; 434 435 memset(&pkt, 0, sizeof(pkt)); 436 pkt.cmd = cpu_to_le32(QRTR_TYPE_DEL_CLIENT); 437 pkt.client.node = cpu_to_le32(node_id); 438 pkt.client.port = cpu_to_le32(port); 439 440 xa_for_each(&local_node->servers, index, srv) { 441 sq.sq_family = AF_QIPCRTR; 442 sq.sq_node = srv->node; 443 sq.sq_port = srv->port; 444 445 msg.msg_name = (struct sockaddr *)&sq; 446 msg.msg_namelen = sizeof(sq); 447 448 ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt)); 449 if (ret < 0 && ret != -ENODEV) { 450 pr_err("failed to send del client cmd\n"); 451 return ret; 452 } 453 } 454 return 0; 455 } 456 457 static int ctrl_cmd_new_server(struct sockaddr_qrtr *from, 458 unsigned int service, unsigned int instance, 459 unsigned int node_id, unsigned int port) 460 { 461 struct qrtr_lookup *lookup; 462 struct qrtr_server *srv; 463 struct list_head *li; 464 int ret = 0; 465 466 /* Ignore specified node and port for local servers */ 467 if (from->sq_node == qrtr_ns.local_node) { 468 node_id = from->sq_node; 469 port = from->sq_port; 470 } 471 472 srv = server_add(service, instance, node_id, port); 473 if (!srv) 474 return -EINVAL; 475 476 if (srv->node == qrtr_ns.local_node) { 477 ret = service_announce_new(&qrtr_ns.bcast_sq, srv); 478 if (ret < 0) { 479 pr_err("failed to announce new service\n"); 480 return ret; 481 } 482 } 483 484 /* Notify any potential lookups about the new server */ 485 list_for_each(li, &qrtr_ns.lookups) { 486 lookup = container_of(li, struct qrtr_lookup, li); 487 if (lookup->service && lookup->service != service) 488 continue; 489 if (lookup->instance && lookup->instance != instance) 490 continue; 491 492 lookup_notify(&lookup->sq, srv, true); 493 } 494 495 return ret; 496 } 497 498 static int ctrl_cmd_del_server(struct sockaddr_qrtr *from, 499 unsigned int service, unsigned int instance, 500 unsigned int node_id, unsigned int port) 501 { 502 struct qrtr_node *node; 503 504 /* Ignore specified node and port for local servers*/ 505 if (from->sq_node == qrtr_ns.local_node) { 506 node_id = from->sq_node; 507 port = from->sq_port; 508 } 509 510 /* Local servers may only unregister themselves */ 511 if (from->sq_node == qrtr_ns.local_node && from->sq_port != port) 512 return -EINVAL; 513 514 node = node_get(node_id); 515 if (!node) 516 return -ENOENT; 517 518 server_del(node, port, true); 519 520 return 0; 521 } 522 523 static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, 524 unsigned int service, unsigned int instance) 525 { 526 struct qrtr_server_filter filter; 527 struct qrtr_lookup *lookup; 528 struct qrtr_server *srv; 529 struct qrtr_node *node; 530 unsigned long node_idx; 531 unsigned long srv_idx; 532 533 /* Accept only local observers */ 534 if (from->sq_node != qrtr_ns.local_node) 535 return -EINVAL; 536 537 lookup = kzalloc(sizeof(*lookup), GFP_KERNEL); 538 if (!lookup) 539 return -ENOMEM; 540 541 lookup->sq = *from; 542 lookup->service = service; 543 lookup->instance = instance; 544 list_add_tail(&lookup->li, &qrtr_ns.lookups); 545 546 memset(&filter, 0, sizeof(filter)); 547 filter.service = service; 548 filter.instance = instance; 549 550 xa_for_each(&nodes, node_idx, node) { 551 xa_for_each(&node->servers, srv_idx, srv) { 552 if (!server_match(srv, &filter)) 553 continue; 554 555 lookup_notify(from, srv, true); 556 } 557 } 558 559 /* Empty notification, to indicate end of listing */ 560 lookup_notify(from, NULL, true); 561 562 return 0; 563 } 564 565 static void ctrl_cmd_del_lookup(struct sockaddr_qrtr *from, 566 unsigned int service, unsigned int instance) 567 { 568 struct qrtr_lookup *lookup; 569 struct list_head *tmp; 570 struct list_head *li; 571 572 list_for_each_safe(li, tmp, &qrtr_ns.lookups) { 573 lookup = container_of(li, struct qrtr_lookup, li); 574 if (lookup->sq.sq_node != from->sq_node) 575 continue; 576 if (lookup->sq.sq_port != from->sq_port) 577 continue; 578 if (lookup->service != service) 579 continue; 580 if (lookup->instance && lookup->instance != instance) 581 continue; 582 583 list_del(&lookup->li); 584 kfree(lookup); 585 } 586 } 587 588 static void qrtr_ns_worker(struct work_struct *work) 589 { 590 const struct qrtr_ctrl_pkt *pkt; 591 size_t recv_buf_size = 4096; 592 struct sockaddr_qrtr sq; 593 struct msghdr msg = { }; 594 unsigned int cmd; 595 ssize_t msglen; 596 void *recv_buf; 597 struct kvec iv; 598 int ret; 599 600 msg.msg_name = (struct sockaddr *)&sq; 601 msg.msg_namelen = sizeof(sq); 602 603 recv_buf = kzalloc(recv_buf_size, GFP_KERNEL); 604 if (!recv_buf) 605 return; 606 607 for (;;) { 608 iv.iov_base = recv_buf; 609 iv.iov_len = recv_buf_size; 610 611 msglen = kernel_recvmsg(qrtr_ns.sock, &msg, &iv, 1, 612 iv.iov_len, MSG_DONTWAIT); 613 614 if (msglen == -EAGAIN) 615 break; 616 617 if (msglen < 0) { 618 pr_err("error receiving packet: %zd\n", msglen); 619 break; 620 } 621 622 pkt = recv_buf; 623 cmd = le32_to_cpu(pkt->cmd); 624 if (cmd < ARRAY_SIZE(qrtr_ctrl_pkt_strings) && 625 qrtr_ctrl_pkt_strings[cmd]) 626 trace_qrtr_ns_message(qrtr_ctrl_pkt_strings[cmd], 627 sq.sq_node, sq.sq_port); 628 629 ret = 0; 630 switch (cmd) { 631 case QRTR_TYPE_HELLO: 632 ret = ctrl_cmd_hello(&sq); 633 break; 634 case QRTR_TYPE_BYE: 635 ret = ctrl_cmd_bye(&sq); 636 break; 637 case QRTR_TYPE_DEL_CLIENT: 638 ret = ctrl_cmd_del_client(&sq, 639 le32_to_cpu(pkt->client.node), 640 le32_to_cpu(pkt->client.port)); 641 break; 642 case QRTR_TYPE_NEW_SERVER: 643 ret = ctrl_cmd_new_server(&sq, 644 le32_to_cpu(pkt->server.service), 645 le32_to_cpu(pkt->server.instance), 646 le32_to_cpu(pkt->server.node), 647 le32_to_cpu(pkt->server.port)); 648 break; 649 case QRTR_TYPE_DEL_SERVER: 650 ret = ctrl_cmd_del_server(&sq, 651 le32_to_cpu(pkt->server.service), 652 le32_to_cpu(pkt->server.instance), 653 le32_to_cpu(pkt->server.node), 654 le32_to_cpu(pkt->server.port)); 655 break; 656 case QRTR_TYPE_EXIT: 657 case QRTR_TYPE_PING: 658 case QRTR_TYPE_RESUME_TX: 659 break; 660 case QRTR_TYPE_NEW_LOOKUP: 661 ret = ctrl_cmd_new_lookup(&sq, 662 le32_to_cpu(pkt->server.service), 663 le32_to_cpu(pkt->server.instance)); 664 break; 665 case QRTR_TYPE_DEL_LOOKUP: 666 ctrl_cmd_del_lookup(&sq, 667 le32_to_cpu(pkt->server.service), 668 le32_to_cpu(pkt->server.instance)); 669 break; 670 } 671 672 if (ret < 0) 673 pr_err("failed while handling packet from %d:%d", 674 sq.sq_node, sq.sq_port); 675 } 676 677 kfree(recv_buf); 678 } 679 680 static void qrtr_ns_data_ready(struct sock *sk) 681 { 682 trace_sk_data_ready(sk); 683 684 queue_work(qrtr_ns.workqueue, &qrtr_ns.work); 685 } 686 687 int qrtr_ns_init(void) 688 { 689 struct sockaddr_qrtr sq; 690 int ret; 691 692 INIT_LIST_HEAD(&qrtr_ns.lookups); 693 INIT_WORK(&qrtr_ns.work, qrtr_ns_worker); 694 695 ret = sock_create_kern(&init_net, AF_QIPCRTR, SOCK_DGRAM, 696 PF_QIPCRTR, &qrtr_ns.sock); 697 if (ret < 0) 698 return ret; 699 700 ret = kernel_getsockname(qrtr_ns.sock, (struct sockaddr *)&sq); 701 if (ret < 0) { 702 pr_err("failed to get socket name\n"); 703 goto err_sock; 704 } 705 706 qrtr_ns.workqueue = alloc_ordered_workqueue("qrtr_ns_handler", 0); 707 if (!qrtr_ns.workqueue) { 708 ret = -ENOMEM; 709 goto err_sock; 710 } 711 712 qrtr_ns.sock->sk->sk_data_ready = qrtr_ns_data_ready; 713 714 sq.sq_port = QRTR_PORT_CTRL; 715 qrtr_ns.local_node = sq.sq_node; 716 717 ret = kernel_bind(qrtr_ns.sock, (struct sockaddr *)&sq, sizeof(sq)); 718 if (ret < 0) { 719 pr_err("failed to bind to socket\n"); 720 goto err_wq; 721 } 722 723 qrtr_ns.bcast_sq.sq_family = AF_QIPCRTR; 724 qrtr_ns.bcast_sq.sq_node = QRTR_NODE_BCAST; 725 qrtr_ns.bcast_sq.sq_port = QRTR_PORT_CTRL; 726 727 ret = say_hello(&qrtr_ns.bcast_sq); 728 if (ret < 0) 729 goto err_wq; 730 731 /* As the qrtr ns socket owner and creator is the same module, we have 732 * to decrease the qrtr module reference count to guarantee that it 733 * remains zero after the ns socket is created, otherwise, executing 734 * "rmmod" command is unable to make the qrtr module deleted after the 735 * qrtr module is inserted successfully. 736 * 737 * However, the reference count is increased twice in 738 * sock_create_kern(): one is to increase the reference count of owner 739 * of qrtr socket's proto_ops struct; another is to increment the 740 * reference count of owner of qrtr proto struct. Therefore, we must 741 * decrement the module reference count twice to ensure that it keeps 742 * zero after server's listening socket is created. Of course, we 743 * must bump the module reference count twice as well before the socket 744 * is closed. 745 */ 746 module_put(qrtr_ns.sock->ops->owner); 747 module_put(qrtr_ns.sock->sk->sk_prot_creator->owner); 748 749 return 0; 750 751 err_wq: 752 destroy_workqueue(qrtr_ns.workqueue); 753 err_sock: 754 sock_release(qrtr_ns.sock); 755 return ret; 756 } 757 EXPORT_SYMBOL_GPL(qrtr_ns_init); 758 759 void qrtr_ns_remove(void) 760 { 761 cancel_work_sync(&qrtr_ns.work); 762 destroy_workqueue(qrtr_ns.workqueue); 763 764 /* sock_release() expects the two references that were put during 765 * qrtr_ns_init(). This function is only called during module remove, 766 * so try_stop_module() has already set the refcnt to 0. Use 767 * __module_get() instead of try_module_get() to successfully take two 768 * references. 769 */ 770 __module_get(qrtr_ns.sock->ops->owner); 771 __module_get(qrtr_ns.sock->sk->sk_prot_creator->owner); 772 sock_release(qrtr_ns.sock); 773 } 774 EXPORT_SYMBOL_GPL(qrtr_ns_remove); 775 776 MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>"); 777 MODULE_DESCRIPTION("Qualcomm IPC Router Nameservice"); 778 MODULE_LICENSE("Dual BSD/GPL"); 779
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.