Print this page
4788 mac shouldn't abuse ddi_get_time(9f)

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/mac/mac_protect.c
          +++ new/usr/src/uts/common/io/mac/mac_protect.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  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) 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   */
       25 +/*
       26 + * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
       27 + */
  25   28  
  26   29  #include <sys/strsun.h>
  27   30  #include <sys/sdt.h>
  28   31  #include <sys/mac.h>
  29   32  #include <sys/mac_impl.h>
  30   33  #include <sys/mac_client_impl.h>
  31   34  #include <sys/mac_client_priv.h>
  32   35  #include <sys/ethernet.h>
  33   36  #include <sys/vlan.h>
  34   37  #include <sys/dlpi.h>
↓ open down ↓ 99 lines elided ↑ open up ↑
 134  137   * may have multiple addresses associated with it.
 135  138   */
 136  139  
 137  140  /*
 138  141   * These are just arbitrary limits meant for preventing abuse (e.g. a user
 139  142   * flooding the network with bogus transactions). They are not meant to be
 140  143   * user-modifiable so they are not exposed as linkprops.
 141  144   */
 142  145  static ulong_t  dhcp_max_pending_txn = 512;
 143  146  static ulong_t  dhcp_max_completed_txn = 512;
 144      -static time_t   txn_cleanup_interval = 60;
      147 +static hrtime_t txn_cleanup_interval = 60 * NANOSEC;
 145  148  
 146  149  /*
 147  150   * DHCPv4 transaction. It may be added to three different tables
 148  151   * (keyed by different fields).
 149  152   */
 150  153  typedef struct dhcpv4_txn {
 151  154          uint32_t                dt_xid;
 152      -        time_t                  dt_timestamp;
      155 +        hrtime_t                dt_timestamp;
 153  156          uint8_t                 dt_cid[DHCP_MAX_OPT_SIZE];
 154  157          uint8_t                 dt_cid_len;
 155  158          ipaddr_t                dt_ipaddr;
 156  159          avl_node_t              dt_node;
 157  160          avl_node_t              dt_ipnode;
 158  161          struct dhcpv4_txn       *dt_next;
 159  162  } dhcpv4_txn_t;
 160  163  
 161  164  /*
 162  165   * DHCPv6 address. May be added to mci_v6_dyn_ip.
↓ open down ↓ 16 lines elided ↑ open up ↑
 179  182          uint_t                  dc_addrcnt;
 180  183          avl_node_t              dc_node;
 181  184  } dhcpv6_cid_t;
 182  185  
 183  186  /*
 184  187   * DHCPv6 transaction. Unlike its v4 counterpart, this object gets freed up
 185  188   * as soon as the transaction completes or expires.
 186  189   */
 187  190  typedef struct dhcpv6_txn {
 188  191          uint32_t                dt_xid;
 189      -        time_t                  dt_timestamp;
      192 +        hrtime_t                dt_timestamp;
 190  193          dhcpv6_cid_t            *dt_cid;
 191  194          avl_node_t              dt_node;
 192  195          struct dhcpv6_txn       *dt_next;
 193  196  } dhcpv6_txn_t;
 194  197  
 195  198  static void     start_txn_cleanup_timer(mac_client_impl_t *);
 196  199  static boolean_t allowed_ips_set(mac_resource_props_t *, uint32_t);
 197  200  
 198  201  #define BUMP_STAT(m, s) (m)->mci_misc_stat.mms_##s++
 199  202  
↓ open down ↓ 248 lines elided ↑ open up ↑
 448  451   */
 449  452  static dhcpv4_txn_t *
 450  453  create_dhcpv4_txn(uint32_t xid, uint8_t *cid, uint8_t cid_len, ipaddr_t ipaddr)
 451  454  {
 452  455          dhcpv4_txn_t    *txn;
 453  456  
 454  457          if ((txn = kmem_zalloc(sizeof (*txn), KM_NOSLEEP)) == NULL)
 455  458                  return (NULL);
 456  459  
 457  460          txn->dt_xid = xid;
 458      -        txn->dt_timestamp = ddi_get_time();
      461 +        txn->dt_timestamp = gethrtime();
 459  462          if (cid_len > 0)
 460  463                  bcopy(cid, &txn->dt_cid, cid_len);
 461  464          txn->dt_cid_len = cid_len;
 462  465          txn->dt_ipaddr = ipaddr;
 463  466          return (txn);
 464  467  }
 465  468  
 466  469  static void
 467  470  free_dhcpv4_txn(dhcpv4_txn_t *txn)
 468  471  {
↓ open down ↓ 36 lines elided ↑ open up ↑
 505  508  txn_cleanup_v4(mac_client_impl_t *mcip)
 506  509  {
 507  510          dhcpv4_txn_t            *txn, *ctxn, *next, *txn_list = NULL;
 508  511  
 509  512          /*
 510  513           * Find stale pending transactions and place them on a list
 511  514           * to be removed.
 512  515           */
 513  516          for (txn = avl_first(&mcip->mci_v4_pending_txn); txn != NULL;
 514  517              txn = avl_walk(&mcip->mci_v4_pending_txn, txn, AVL_AFTER)) {
 515      -                if (ddi_get_time() - txn->dt_timestamp >
 516      -                    txn_cleanup_interval) {
      518 +                if (gethrtime() - txn->dt_timestamp > txn_cleanup_interval) {
 517  519                          DTRACE_PROBE2(found__expired__txn,
 518  520                              mac_client_impl_t *, mcip,
 519  521                              dhcpv4_txn_t *, txn);
 520  522  
 521  523                          txn->dt_next = txn_list;
 522  524                          txn_list = txn;
 523  525                  }
 524  526          }
 525  527  
 526  528          /*
↓ open down ↓ 83 lines elided ↑ open up ↑
 610  612          }
 611  613  
 612  614          /*
 613  615           * If a pending txn already exists, we'll update its timestamp so
 614  616           * it won't get flushed by the timer. We don't need to create new
 615  617           * txns for retransmissions.
 616  618           */
 617  619          if ((txn = find_dhcpv4_pending_txn(mcip, dh4->xid)) != NULL) {
 618  620                  DTRACE_PROBE2(update, mac_client_impl_t *, mcip,
 619  621                      dhcpv4_txn_t *, txn);
 620      -                txn->dt_timestamp = ddi_get_time();
      622 +                txn->dt_timestamp = gethrtime();
 621  623                  goto done;
 622  624          }
 623  625  
 624  626          if (get_dhcpv4_option(dh4, end, CD_REQUESTED_IP_ADDR,
 625  627              &opt, &opt_len) != 0 || opt_len != sizeof (ipaddr)) {
 626  628                  DTRACE_PROBE2(ipaddr__not__found, mac_client_impl_t *, mcip,
 627  629                      struct dhcp *, dh4);
 628  630                  goto done;
 629  631          }
 630  632          bcopy(opt, &ipaddr, sizeof (ipaddr));
↓ open down ↓ 478 lines elided ↑ open up ↑
1109 1111  static dhcpv6_txn_t *
1110 1112  create_dhcpv6_txn(uint32_t xid, dhcpv6_cid_t *cid)
1111 1113  {
1112 1114          dhcpv6_txn_t    *txn;
1113 1115  
1114 1116          if ((txn = kmem_zalloc(sizeof (dhcpv6_txn_t), KM_NOSLEEP)) == NULL)
1115 1117                  return (NULL);
1116 1118  
1117 1119          txn->dt_xid = xid;
1118 1120          txn->dt_cid = cid;
1119      -        txn->dt_timestamp = ddi_get_time();
     1121 +        txn->dt_timestamp = gethrtime();
1120 1122          return (txn);
1121 1123  }
1122 1124  
1123 1125  static void
1124 1126  free_dhcpv6_txn(dhcpv6_txn_t *txn)
1125 1127  {
1126 1128          if (txn->dt_cid != NULL)
1127 1129                  free_dhcpv6_cid(txn->dt_cid);
1128 1130          kmem_free(txn, sizeof (dhcpv6_txn_t));
1129 1131  }
↓ open down ↓ 46 lines elided ↑ open up ↑
1176 1178  txn_cleanup_v6(mac_client_impl_t *mcip)
1177 1179  {
1178 1180          dhcpv6_txn_t            *txn, *next, *txn_list = NULL;
1179 1181  
1180 1182          /*
1181 1183           * Find stale pending transactions and place them on a list
1182 1184           * to be removed.
1183 1185           */
1184 1186          for (txn = avl_first(&mcip->mci_v6_pending_txn); txn != NULL;
1185 1187              txn = avl_walk(&mcip->mci_v6_pending_txn, txn, AVL_AFTER)) {
1186      -                if (ddi_get_time() - txn->dt_timestamp >
1187      -                    txn_cleanup_interval) {
     1188 +                if (gethrtime() - txn->dt_timestamp > txn_cleanup_interval) {
1188 1189                          DTRACE_PROBE2(found__expired__txn,
1189 1190                              mac_client_impl_t *, mcip,
1190 1191                              dhcpv6_txn_t *, txn);
1191 1192  
1192 1193                          txn->dt_next = txn_list;
1193 1194                          txn_list = txn;
1194 1195                  }
1195 1196          }
1196 1197  
1197 1198          /*
↓ open down ↓ 43 lines elided ↑ open up ↑
1241 1242  
1242 1243          mutex_enter(&mcip->mci_protect_lock);
1243 1244          if (mtype == DHCPV6_MSG_RELEASE) {
1244 1245                  release_dhcpv6_cid(mcip, cid);
1245 1246                  goto done;
1246 1247          }
1247 1248          xid = DHCPV6_GET_TRANSID(dh6);
1248 1249          if ((txn = find_dhcpv6_pending_txn(mcip, xid)) != NULL) {
1249 1250                  DTRACE_PROBE2(update, mac_client_impl_t *, mcip,
1250 1251                      dhcpv6_txn_t *, txn);
1251      -                txn->dt_timestamp = ddi_get_time();
     1252 +                txn->dt_timestamp = gethrtime();
1252 1253                  goto done;
1253 1254          }
1254 1255          if ((txn = create_dhcpv6_txn(xid, cid)) == NULL)
1255 1256                  goto done;
1256 1257  
1257 1258          cid = NULL;
1258 1259          if (insert_dhcpv6_pending_txn(mcip, txn) != 0) {
1259 1260                  DTRACE_PROBE2(insert__failed, mac_client_impl_t *, mcip,
1260 1261                      dhcpv6_txn_t *, txn);
1261 1262                  free_dhcpv6_txn(txn);
↓ open down ↓ 88 lines elided ↑ open up ↑
1350 1351          txn_cleanup_v6(mcip);
1351 1352  
1352 1353          /*
1353 1354           * Restart timer if pending transactions still exist.
1354 1355           */
1355 1356          if (!avl_is_empty(&mcip->mci_v4_pending_txn) ||
1356 1357              !avl_is_empty(&mcip->mci_v6_pending_txn)) {
1357 1358                  DTRACE_PROBE1(restarting__timer, mac_client_impl_t *, mcip);
1358 1359  
1359 1360                  mcip->mci_txn_cleanup_tid = timeout(txn_cleanup_timer, mcip,
1360      -                    drv_usectohz(txn_cleanup_interval * 1000000));
     1361 +                    drv_usectohz(txn_cleanup_interval / (NANOSEC / MICROSEC)));
1361 1362          }
1362 1363          mutex_exit(&mcip->mci_protect_lock);
1363 1364  }
1364 1365  
1365 1366  static void
1366 1367  start_txn_cleanup_timer(mac_client_impl_t *mcip)
1367 1368  {
1368 1369          ASSERT(MUTEX_HELD(&mcip->mci_protect_lock));
1369 1370          if (mcip->mci_txn_cleanup_tid == 0) {
1370 1371                  mcip->mci_txn_cleanup_tid = timeout(txn_cleanup_timer, mcip,
1371      -                    drv_usectohz(txn_cleanup_interval * 1000000));
     1372 +                    drv_usectohz(txn_cleanup_interval / (NANOSEC / MICROSEC)));
1372 1373          }
1373 1374  }
1374 1375  
1375 1376  static void
1376 1377  cancel_txn_cleanup_timer(mac_client_impl_t *mcip)
1377 1378  {
1378 1379          timeout_id_t    tid;
1379 1380  
1380 1381          ASSERT(MUTEX_HELD(&mcip->mci_protect_lock));
1381 1382  
↓ open down ↓ 923 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX