Print this page
OS-7088 cyclics corked on overlay socket with full queue

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/overlay/overlay.c
          +++ new/usr/src/uts/common/io/overlay/overlay.c
↓ open down ↓ 2 lines elided ↑ open up ↑
   3    3   * Common Development and Distribution License ("CDDL"), version 1.0.
   4    4   * You may only use this file in accordance with the terms of version
   5    5   * 1.0 of the CDDL.
   6    6   *
   7    7   * A full copy of the text of the CDDL should have accompanied this
   8    8   * source.  A copy of the CDDL is also available via the Internet at
   9    9   * http://www.illumos.org/license/CDDL.
  10   10   */
  11   11  
  12   12  /*
  13      - * Copyright 2016 Joyent, Inc.
       13 + * Copyright 2018 Joyent, Inc.
  14   14   */
  15   15  
  16   16  /*
  17   17   * Overlay Devices
  18   18   *
  19   19   * Overlay devices provide a means for creating overlay networks, a means of
  20   20   * multiplexing multiple logical, isolated, and discrete layer two and layer
  21   21   * three networks on top of one physical network.
  22   22   *
  23   23   * In general, these overlay devices encapsulate the logic to answer two
↓ open down ↓ 1023 lines elided ↑ open up ↑
1047 1047  mblk_t *
1048 1048  overlay_m_tx(void *arg, mblk_t *mp_chain)
1049 1049  {
1050 1050          overlay_dev_t *odd = arg;
1051 1051          mblk_t *mp, *ep;
1052 1052          int ret;
1053 1053          ovep_encap_info_t einfo;
1054 1054          struct msghdr hdr;
1055 1055  
1056 1056          mutex_enter(&odd->odd_lock);
     1057 +        ASSERT0(odd->odd_flags & OVERLAY_F_TXSTOPPED);
1057 1058          if ((odd->odd_flags & OVERLAY_F_MDDROP) ||
1058 1059              !(odd->odd_flags & OVERLAY_F_IN_MUX)) {
1059 1060                  mutex_exit(&odd->odd_lock);
1060 1061                  freemsgchain(mp_chain);
1061 1062                  return (NULL);
1062 1063          }
1063 1064          overlay_io_start(odd, OVERLAY_F_IN_TX);
1064 1065          mutex_exit(&odd->odd_lock);
1065 1066  
1066 1067          bzero(&hdr, sizeof (struct msghdr));
1067 1068  
1068 1069          bzero(&einfo, sizeof (ovep_encap_info_t));
1069 1070          einfo.ovdi_id = odd->odd_vid;
1070 1071          mp = mp_chain;
1071 1072          while (mp != NULL) {
1072 1073                  socklen_t slen;
1073 1074                  struct sockaddr_storage storage;
     1075 +#ifdef OVERLAY_FC_TEST
     1076 +                /* Can deal with it being NULL later... */
     1077 +                mblk_t *save_mp = msgpullup(mp, -1);
     1078 +#endif
1074 1079  
1075 1080                  mp_chain = mp->b_next;
1076 1081                  mp->b_next = NULL;
1077 1082                  ep = NULL;
1078 1083  
1079 1084                  ret = overlay_target_lookup(odd, mp,
1080 1085                      (struct sockaddr *)&storage, &slen);
1081 1086                  if (ret != OVERLAY_TARGET_OK) {
1082 1087                          if (ret == OVERLAY_TARGET_DROP)
1083 1088                                  freemsg(mp);
1084 1089                          mp = mp_chain;
     1090 +#ifdef OVERLAY_FC_TEST
     1091 +                        freemsg(save_mp);       /* Handles NULL and non-NULL */
     1092 +#endif
1085 1093                          continue;
1086 1094                  }
1087 1095  
1088 1096                  hdr.msg_name = &storage;
1089 1097                  hdr.msg_namelen = slen;
1090 1098  
1091 1099                  ret = odd->odd_plugin->ovp_ops->ovpo_encap(odd->odd_mh, mp,
1092 1100                      &einfo, &ep);
1093 1101                  if (ret != 0 || ep == NULL) {
     1102 +#ifdef OVERLAY_FC_TEST
     1103 +                        freemsg(save_mp);       /* Handles NULL and non-NULL */
     1104 +#endif
1094 1105                          freemsg(mp);
1095 1106                          goto out;
1096 1107                  }
1097 1108  
1098 1109                  ASSERT(ep->b_cont == mp || ep == mp);
1099 1110                  ret = overlay_mux_tx(odd->odd_mux, &hdr, ep);
1100      -                if (ret != 0)
     1111 +                if (ret != 0) {
     1112 +                        if (ret != EWOULDBLOCK) {
     1113 +                                /*
     1114 +                                 * Get rid of the packets, something ELSE is
     1115 +                                 * wrong with the socket, and we really should
     1116 +                                 * just drop the packets for now.
     1117 +                                 */
     1118 +#ifdef OVERLAY_FC_TEST
     1119 +                                freemsg(save_mp);
     1120 +                                save_mp = NULL;
     1121 +#endif
     1122 +                                freemsgchain(mp_chain);
     1123 +                                mp_chain = NULL;
     1124 +                        }
     1125 +#ifdef OVERLAY_FC_TEST
     1126 +                        if (save_mp != NULL) {
     1127 +                                /*
     1128 +                                 * Return the dropped mp here to see how
     1129 +                                 * upper-layer MAC reacts to it.
     1130 +                                 */
     1131 +                                save_mp->b_next = mp_chain;
     1132 +                                mp_chain = save_mp;
     1133 +                        }
     1134 +#endif
     1135 +                        /*
     1136 +                         * EWOULDBLOCK is a special case.  Return the rest of
     1137 +                         * the mp_chain to MAC and have this instance be
     1138 +                         * marked as unable to transmit.  Re-enable this
     1139 +                         * instance when the mux's socket is able to send data
     1140 +                         * again ("cansend" callback).
     1141 +                         */
1101 1142                          goto out;
     1143 +                }
1102 1144  
1103 1145                  mp = mp_chain;
1104 1146          }
1105 1147  
1106 1148  out:
1107 1149          mutex_enter(&odd->odd_lock);
1108 1150          overlay_io_done(odd, OVERLAY_F_IN_TX);
     1151 +        if (mp_chain != NULL) {
     1152 +                /* Note that we're returning an unsent chain to MAC. */
     1153 +                odd->odd_flags |= OVERLAY_F_TXSTOPPED;
     1154 +        }
1109 1155          mutex_exit(&odd->odd_lock);
1110 1156          return (mp_chain);
1111 1157  }
1112 1158  
1113 1159  /* ARGSUSED */
1114 1160  static void
1115 1161  overlay_m_ioctl(void *arg, queue_t *q, mblk_t *mp)
1116 1162  {
1117 1163          miocnak(q, mp, 0, ENOTSUP);
1118 1164  }
↓ open down ↓ 1066 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX