Print this page
8626 make pcplusmp and apix warning-free
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/i86pc/io/mp_platform_misc.c
          +++ new/usr/src/uts/i86pc/io/mp_platform_misc.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  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   * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
       23 + * Copyright 2017 Joyent, Inc.
  23   24   */
  24   25  /*
  25   26   * Copyright (c) 2010, Intel Corporation.
  26   27   * All rights reserved.
  27   28   */
  28   29  
  29   30  /*
  30   31   * PSMI 1.1 extensions are supported only in 2.6 and later versions.
  31   32   * PSMI 1.2 extensions are supported only in 2.7 and later versions.
  32   33   * PSMI 1.3 and 1.4 extensions are supported in Solaris 10.
↓ open down ↓ 604 lines elided ↑ open up ↑
 637  638                           * we need to subtract APIC_BASE_VECT from the
 638  639                           * hardware-vector-equivalent (in hwpri).  Since hwpri
 639  640                           * is already shifted, we shift APIC_BASE_VECT before
 640  641                           * doing the subtraction.
 641  642                           */
 642  643                          hwpri -= (APIC_BASE_VECT >> APIC_IPL_SHIFT);
 643  644  
 644  645                          ASSERT(hwpri >= 0);
 645  646                          ASSERT(hwpri < MAXIPL);
 646  647                          max_ipl = apic_vectortoipl[hwpri];
 647      -                        apic_ipls[apic_ipls_index] = max_ipl;
      648 +                        apic_ipls[apic_ipls_index] = (uchar_t)max_ipl;
 648  649  
 649  650                          irqp = irqheadptr;
 650  651                          while (irqp) {
 651  652                                  irqp->airq_ipl = (uchar_t)max_ipl;
 652  653                                  irqp = irqp->airq_next;
 653  654                          }
 654  655                  } else {
 655  656                          /*
 656  657                           * No more devices on this IRQ, so reset this vector's
 657  658                           * element in apic_ipls to the original IPL for this
↓ open down ↓ 280 lines elided ↑ open up ↑
 938  939          ASSERT(IRQINDEX(newirq) == irqno);
 939  940          ASSERT(apic_irq_table[irqno]);
 940  941          return (newirq);
 941  942  }
 942  943  
 943  944  /*
 944  945   * Attempt to share vector with someone else
 945  946   */
 946  947  static int
 947  948  apic_share_vector(int irqno, iflag_t *intr_flagp, short intr_index, int ipl,
 948      -        uchar_t ioapicindex, uchar_t ipin, apic_irq_t **irqptrp)
      949 +    uchar_t ioapicindex, uchar_t ipin, apic_irq_t **irqptrp)
 949  950  {
 950  951  #ifdef DEBUG
 951  952          apic_irq_t *tmpirqp = NULL;
 952  953  #endif /* DEBUG */
 953  954          apic_irq_t *irqptr, dummyirq;
 954  955          int     newirq, chosen_irq = -1, share = 127;
 955  956          int     lowest, highest, i;
 956  957          uchar_t share_id;
 957  958  
 958  959          DDI_INTR_IMPLDBG((CE_CONT, "apic_share_vector: irqno=0x%x "
↓ open down ↓ 84 lines elided ↑ open up ↑
1043 1044   * is used already, we will try to allocate a new irqno.
1044 1045   *
1045 1046   * Return value:
1046 1047   *      Success: irqno
1047 1048   *      Failure: -1
1048 1049   */
1049 1050  static int
1050 1051  apic_setup_irq_table(dev_info_t *dip, int irqno, struct apic_io_intr *intrp,
1051 1052      struct intrspec *ispec, iflag_t *intr_flagp, int type)
1052 1053  {
1053      -        int origirq = ispec->intrspec_vec;
1054      -        uchar_t ipl = ispec->intrspec_pri;
     1054 +        int origirq;
     1055 +        uchar_t ipl;
1055 1056          int     newirq, intr_index;
1056 1057          uchar_t ipin, ioapic, ioapicindex, vector;
1057 1058          apic_irq_t *irqptr;
1058 1059          major_t major;
1059 1060          dev_info_t      *sdip;
1060 1061  
     1062 +        ASSERT(ispec != NULL);
     1063 +
     1064 +        origirq = ispec->intrspec_vec;
     1065 +        ipl = ispec->intrspec_pri;
     1066 +
1061 1067          DDI_INTR_IMPLDBG((CE_CONT, "apic_setup_irq_table: dip=0x%p type=%d "
1062 1068              "irqno=0x%x origirq=0x%x\n", (void *)dip, type, irqno, origirq));
1063 1069  
1064      -        ASSERT(ispec != NULL);
1065      -
1066 1070          major =  (dip != NULL) ? ddi_driver_major(dip) : 0;
1067 1071  
1068 1072          if (DDI_INTR_IS_MSI_OR_MSIX(type)) {
1069 1073                  /* MSI/X doesn't need to setup ioapic stuffs */
1070 1074                  ioapicindex = 0xff;
1071 1075                  ioapic = 0xff;
1072 1076                  ipin = (uchar_t)0xff;
1073 1077                  intr_index = (type == DDI_INTR_TYPE_MSI) ? MSI_INDEX :
1074 1078                      MSIX_INDEX;
1075 1079                  mutex_enter(&airq_mutex);
↓ open down ↓ 38 lines elided ↑ open up ↑
1114 1118                  }
1115 1119  
1116 1120          } else {
1117 1121                  /* default configuration */
1118 1122                  ioapicindex = 0;
1119 1123                  ioapic = apic_io_id[ioapicindex];
1120 1124                  ipin = (uchar_t)irqno;
1121 1125                  intr_index = DEFAULT_INDEX;
1122 1126          }
1123 1127  
1124      -        if (ispec == NULL) {
1125      -                APIC_VERBOSE_IOAPIC((CE_WARN, "No intrspec for irqno = %x\n",
1126      -                    irqno));
1127      -        } else if ((vector = apic_allocate_vector(ipl, irqno, 0)) == 0) {
     1128 +        if ((vector = apic_allocate_vector(ipl, irqno, 0)) == 0) {
1128 1129                  if ((newirq = apic_share_vector(irqno, intr_flagp, intr_index,
1129 1130                      ipl, ioapicindex, ipin, &irqptr)) != -1) {
1130 1131                          irqptr->airq_ipl = ipl;
1131 1132                          irqptr->airq_origirq = (uchar_t)origirq;
1132 1133                          irqptr->airq_dip = dip;
1133 1134                          irqptr->airq_major = major;
1134 1135                          sdip = apic_irq_table[IRQINDEX(newirq)]->airq_dip;
1135 1136                          /* This is OK to do really */
1136 1137                          if (sdip == NULL) {
1137 1138                                  cmn_err(CE_WARN, "Sharing vectors: %s"
↓ open down ↓ 83 lines elided ↑ open up ↑
1221 1222          char    prop_name[32];
1222 1223          ulong_t iflag;
1223 1224  
1224 1225  
1225 1226          if (apic_intr_policy == INTR_LOWEST_PRIORITY)
1226 1227                  return (IRQ_UNBOUND);
1227 1228  
1228 1229          if (apic_nproc == 1)
1229 1230                  return (0);
1230 1231  
1231      -        drv_name = NULL;
1232      -        rc = DDI_PROP_NOT_FOUND;
1233      -        major = (major_t)-1;
1234      -        if (dip != NULL) {
1235      -                name = ddi_get_name(dip);
1236      -                major = ddi_name_to_major(name);
1237      -                drv_name = ddi_major_to_name(major);
1238      -                instance = ddi_get_instance(dip);
1239      -                if (apic_intr_policy == INTR_ROUND_ROBIN_WITH_AFFINITY) {
1240      -                        i = apic_min_device_irq;
1241      -                        for (; i <= apic_max_device_irq; i++) {
     1232 +        if (dip == NULL) {
     1233 +                iflag = intr_clear();
     1234 +                lock_set(&apic_ioapic_lock);
     1235 +                bind_cpu = apic_get_next_bind_cpu();
     1236 +                lock_clear(&apic_ioapic_lock);
     1237 +                intr_restore(iflag);
1242 1238  
1243      -                                if ((i == irq) || (apic_irq_table[i] == NULL) ||
1244      -                                    (apic_irq_table[i]->airq_mps_intr_index
1245      -                                    == FREE_INDEX))
1246      -                                        continue;
     1239 +                cmn_err(CE_CONT, "!%s: irq 0x%x "
     1240 +                    "vector 0x%x ioapic 0x%x intin 0x%x is bound to cpu %d\n",
     1241 +                    psm_name, irq, apic_irq_table[irq]->airq_vector, ioapicid,
     1242 +                    intin, bind_cpu & ~IRQ_USER_BOUND);
1247 1243  
1248      -                                if ((apic_irq_table[i]->airq_major == major) &&
1249      -                                    (!(apic_irq_table[i]->airq_cpu &
1250      -                                    IRQ_USER_BOUND))) {
     1244 +                return ((uint32_t)bind_cpu);
     1245 +        }
1251 1246  
1252      -                                        cpu = apic_irq_table[i]->airq_cpu;
     1247 +        name = ddi_get_name(dip);
     1248 +        major = ddi_name_to_major(name);
     1249 +        drv_name = ddi_major_to_name(major);
     1250 +        instance = ddi_get_instance(dip);
     1251 +        if (apic_intr_policy == INTR_ROUND_ROBIN_WITH_AFFINITY) {
     1252 +                i = apic_min_device_irq;
     1253 +                for (; i <= apic_max_device_irq; i++) {
     1254 +                        if ((i == irq) || (apic_irq_table[i] == NULL) ||
     1255 +                            (apic_irq_table[i]->airq_mps_intr_index
     1256 +                            == FREE_INDEX))
     1257 +                                continue;
1253 1258  
1254      -                                        cmn_err(CE_CONT,
1255      -                                            "!%s: %s (%s) instance #%d "
1256      -                                            "irq 0x%x vector 0x%x ioapic 0x%x "
1257      -                                            "intin 0x%x is bound to cpu %d\n",
1258      -                                            psm_name,
1259      -                                            name, drv_name, instance, irq,
1260      -                                            apic_irq_table[irq]->airq_vector,
1261      -                                            ioapicid, intin, cpu);
1262      -                                        return (cpu);
1263      -                                }
     1259 +                        if ((apic_irq_table[i]->airq_major == major) &&
     1260 +                            (!(apic_irq_table[i]->airq_cpu & IRQ_USER_BOUND))) {
     1261 +                                cpu = apic_irq_table[i]->airq_cpu;
     1262 +
     1263 +                                cmn_err(CE_CONT,
     1264 +                                    "!%s: %s (%s) instance #%d "
     1265 +                                    "irq 0x%x vector 0x%x ioapic 0x%x "
     1266 +                                    "intin 0x%x is bound to cpu %d\n",
     1267 +                                    psm_name,
     1268 +                                    name, drv_name, instance, irq,
     1269 +                                    apic_irq_table[irq]->airq_vector,
     1270 +                                    ioapicid, intin, cpu);
     1271 +                                return (cpu);
1264 1272                          }
1265 1273                  }
1266      -                /*
1267      -                 * search for "drvname"_intpt_bind_cpus property first, the
1268      -                 * syntax of the property should be "a[,b,c,...]" where
1269      -                 * instance 0 binds to cpu a, instance 1 binds to cpu b,
1270      -                 * instance 3 binds to cpu c...
1271      -                 * ddi_getlongprop() will search /option first, then /
1272      -                 * if "drvname"_intpt_bind_cpus doesn't exist, then find
1273      -                 * intpt_bind_cpus property.  The syntax is the same, and
1274      -                 * it applies to all the devices if its "drvname" specific
1275      -                 * property doesn't exist
1276      -                 */
1277      -                (void) strcpy(prop_name, drv_name);
1278      -                (void) strcat(prop_name, "_intpt_bind_cpus");
1279      -                rc = ddi_getlongprop(DDI_DEV_T_ANY, dip, 0, prop_name,
1280      -                    (caddr_t)&prop_val, &prop_len);
1281      -                if (rc != DDI_PROP_SUCCESS) {
1282      -                        rc = ddi_getlongprop(DDI_DEV_T_ANY, dip, 0,
1283      -                            "intpt_bind_cpus", (caddr_t)&prop_val, &prop_len);
1284      -                }
1285 1274          }
     1275 +        /*
     1276 +         * search for "drvname"_intpt_bind_cpus property first, the
     1277 +         * syntax of the property should be "a[,b,c,...]" where
     1278 +         * instance 0 binds to cpu a, instance 1 binds to cpu b,
     1279 +         * instance 3 binds to cpu c...
     1280 +         * ddi_getlongprop() will search /option first, then /
     1281 +         * if "drvname"_intpt_bind_cpus doesn't exist, then find
     1282 +         * intpt_bind_cpus property.  The syntax is the same, and
     1283 +         * it applies to all the devices if its "drvname" specific
     1284 +         * property doesn't exist
     1285 +         */
     1286 +        (void) strcpy(prop_name, drv_name);
     1287 +        (void) strcat(prop_name, "_intpt_bind_cpus");
     1288 +        rc = ddi_getlongprop(DDI_DEV_T_ANY, dip, 0, prop_name,
     1289 +            (caddr_t)&prop_val, &prop_len);
     1290 +        if (rc != DDI_PROP_SUCCESS) {
     1291 +                rc = ddi_getlongprop(DDI_DEV_T_ANY, dip, 0,
     1292 +                    "intpt_bind_cpus", (caddr_t)&prop_val, &prop_len);
     1293 +        }
1286 1294          if (rc == DDI_PROP_SUCCESS) {
1287 1295                  for (i = count = 0; i < (prop_len - 1); i++)
1288 1296                          if (prop_val[i] == ',')
1289 1297                                  count++;
1290 1298                  if (prop_val[i-1] != ',')
1291 1299                          count++;
1292 1300                  /*
1293 1301                   * if somehow the binding instances defined in the
1294 1302                   * property are not enough for this instno., then
1295 1303                   * reuse the pattern for the next instance until
↓ open down ↓ 14 lines elided ↑ open up ↑
1310 1318                          rc = DDI_PROP_NOT_FOUND;
1311 1319                  } else {
1312 1320                          /* indicate that we are bound at user request */
1313 1321                          bind_cpu |= IRQ_USER_BOUND;
1314 1322                  }
1315 1323                  /*
1316 1324                   * no need to check apic_cpus[].aci_status, if specific CPU is
1317 1325                   * not up, then post_cpu_start will handle it.
1318 1326                   */
1319 1327          }
     1328 +
1320 1329          if (rc != DDI_PROP_SUCCESS) {
1321 1330                  iflag = intr_clear();
1322 1331                  lock_set(&apic_ioapic_lock);
1323 1332                  bind_cpu = apic_get_next_bind_cpu();
1324 1333                  lock_clear(&apic_ioapic_lock);
1325 1334                  intr_restore(iflag);
1326 1335          }
1327 1336  
1328      -        if (drv_name != NULL)
1329      -                cmn_err(CE_CONT, "!%s: %s (%s) instance %d irq 0x%x "
1330      -                    "vector 0x%x ioapic 0x%x intin 0x%x is bound to cpu %d\n",
1331      -                    psm_name, name, drv_name, instance, irq,
1332      -                    apic_irq_table[irq]->airq_vector, ioapicid, intin,
1333      -                    bind_cpu & ~IRQ_USER_BOUND);
1334      -        else
1335      -                cmn_err(CE_CONT, "!%s: irq 0x%x "
1336      -                    "vector 0x%x ioapic 0x%x intin 0x%x is bound to cpu %d\n",
1337      -                    psm_name, irq, apic_irq_table[irq]->airq_vector, ioapicid,
1338      -                    intin, bind_cpu & ~IRQ_USER_BOUND);
     1337 +        cmn_err(CE_CONT, "!%s: %s (%s) instance %d irq 0x%x "
     1338 +            "vector 0x%x ioapic 0x%x intin 0x%x is bound to cpu %d\n",
     1339 +            psm_name, name, drv_name, instance, irq,
     1340 +            apic_irq_table[irq]->airq_vector, ioapicid, intin,
     1341 +            bind_cpu & ~IRQ_USER_BOUND);
1339 1342  
1340 1343          return ((uint32_t)bind_cpu);
1341 1344  }
1342 1345  
1343 1346  /*
1344 1347   * Mark vector as being in the process of being deleted. Interrupts
1345 1348   * may still come in on some CPU. The moment an interrupt comes with
1346 1349   * the new vector, we know we can free the old one. Called only from
1347 1350   * addspl and delspl with interrupts disabled. Because an interrupt
1348 1351   * can be shared, but no interrupt from either device may come in,
↓ open down ↓ 865 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX