Print this page
12976 system panics with error in IP module
Reviewed by: Andy Fiddaman <andy@omniosce.org>
Reviewed by: Paul Winder <p.winder@me.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/inet/tcp/tcp.c
          +++ new/usr/src/uts/common/inet/tcp/tcp.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  24      - * Copyright 2019 Joyent, Inc.
  25   24   * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
  26   25   * Copyright (c) 2013, 2017 by Delphix. All rights reserved.
  27   26   * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
       27 + * Copyright 2020 Joyent, Inc.
  28   28   */
  29   29  /* Copyright (c) 1990 Mentat Inc. */
  30   30  
  31   31  #include <sys/types.h>
  32   32  #include <sys/stream.h>
  33   33  #include <sys/strsun.h>
  34   34  #include <sys/strsubr.h>
  35   35  #include <sys/stropts.h>
  36   36  #include <sys/strlog.h>
  37   37  #define _SUN_TPI_VERSION 2
↓ open down ↓ 974 lines elided ↑ open up ↑
1012 1012          connp->conn_wq = NULL;
1013 1013  
1014 1014          /* Signal closing thread that it can complete close */
1015 1015          mutex_enter(&tcp->tcp_closelock);
1016 1016          tcp->tcp_closed = 1;
1017 1017          cv_signal(&tcp->tcp_closecv);
1018 1018          mutex_exit(&tcp->tcp_closelock);
1019 1019  
1020 1020          /* If we have an upper handle (socket), release it */
1021 1021          if (IPCL_IS_NONSTR(connp)) {
1022      -                ASSERT(connp->conn_upper_handle != NULL);
1023      -                (*connp->conn_upcalls->su_closed)(connp->conn_upper_handle);
     1022 +                sock_upcalls_t *upcalls = connp->conn_upcalls;
     1023 +                sock_upper_handle_t handle = connp->conn_upper_handle;
     1024 +
     1025 +                ASSERT(upcalls != NULL);
     1026 +                ASSERT(upcalls->su_closed != NULL);
     1027 +                ASSERT(handle != NULL);
     1028 +                /*
     1029 +                 * Set these to NULL first because closed() will free upper
     1030 +                 * structures.  Acquire conn_lock because an external caller
     1031 +                 * like conn_get_socket_info() will upcall if these are
     1032 +                 * non-NULL.
     1033 +                 */
     1034 +                mutex_enter(&connp->conn_lock);
1024 1035                  connp->conn_upper_handle = NULL;
1025 1036                  connp->conn_upcalls = NULL;
     1037 +                mutex_exit(&connp->conn_lock);
     1038 +                upcalls->su_closed(handle);
1026 1039          }
1027 1040  }
1028 1041  
1029 1042  void
1030 1043  tcp_close_common(conn_t *connp, int flags)
1031 1044  {
1032 1045          tcp_t           *tcp = connp->conn_tcp;
1033 1046          mblk_t          *mp = &tcp->tcp_closemp;
1034 1047          boolean_t       conn_ioctl_cleanup_reqd = B_FALSE;
1035 1048          mblk_t          *bp;
↓ open down ↓ 378 lines elided ↑ open up ↑
1414 1427          if (tcp->tcp_cc_algo != NULL && tcp->tcp_cc_algo->cb_destroy != NULL)
1415 1428                  tcp->tcp_cc_algo->cb_destroy(&tcp->tcp_ccv);
1416 1429  
1417 1430          /*
1418 1431           * If this is a non-STREAM socket still holding on to an upper
1419 1432           * handle, release it. As a result of fallback we might also see
1420 1433           * STREAMS based conns with upper handles, in which case there is
1421 1434           * nothing to do other than clearing the field.
1422 1435           */
1423 1436          if (connp->conn_upper_handle != NULL) {
     1437 +                sock_upcalls_t *upcalls = connp->conn_upcalls;
     1438 +                sock_upper_handle_t handle = connp->conn_upper_handle;
     1439 +
     1440 +                /*
     1441 +                 * Set these to NULL first because closed() will free upper
     1442 +                 * structures.  Acquire conn_lock because an external caller
     1443 +                 * like conn_get_socket_info() will upcall if these are
     1444 +                 * non-NULL.
     1445 +                 */
     1446 +                mutex_enter(&connp->conn_lock);
     1447 +                connp->conn_upper_handle = NULL;
     1448 +                connp->conn_upcalls = NULL;
     1449 +                mutex_exit(&connp->conn_lock);
1424 1450                  if (IPCL_IS_NONSTR(connp)) {
1425      -                        (*connp->conn_upcalls->su_closed)(
1426      -                            connp->conn_upper_handle);
     1451 +                        ASSERT(upcalls != NULL);
     1452 +                        ASSERT(upcalls->su_closed != NULL);
     1453 +                        ASSERT(handle != NULL);
     1454 +                        upcalls->su_closed(handle);
1427 1455                          tcp->tcp_detached = B_TRUE;
1428 1456                  }
1429      -                connp->conn_upper_handle = NULL;
1430      -                connp->conn_upcalls = NULL;
1431 1457          }
1432 1458  }
1433 1459  
1434 1460  /*
1435 1461   * tcp_get_conn/tcp_free_conn
1436 1462   *
1437 1463   * tcp_get_conn is used to get a clean tcp connection structure.
1438 1464   * It tries to reuse the connections put on the freelist by the
1439 1465   * time_wait_collector failing which it goes to kmem_cache. This
1440 1466   * way has two benefits compared to just allocating from and
↓ open down ↓ 3042 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX