Print this page
OS-2366 ddi_periodic_add(9F) is entirely rubbish

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/i86pc/io/apix/apix.c
          +++ new/usr/src/uts/i86pc/io/apix/apix.c
↓ open down ↓ 19 lines elided ↑ open up ↑
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   */
  25   25  /*
  26   26   * Copyright (c) 2010, Intel Corporation.
  27   27   * All rights reserved.
  28   28   */
  29   29  /*
  30      - * Copyright (c) 2012, Joyent, Inc.  All rights reserved.
       30 + * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
  31   31   */
  32   32  
  33   33  /*
  34   34   * To understand how the apix module interacts with the interrupt subsystem read
  35   35   * the theory statement in uts/i86pc/os/intr.c.
  36   36   */
  37   37  
  38   38  /*
  39   39   * PSMI 1.1 extensions are supported only in 2.6 and later versions.
  40   40   * PSMI 1.2 extensions are supported only in 2.7 and later versions.
↓ open down ↓ 27 lines elided ↑ open up ↑
  68   68  #include <sys/trap.h>
  69   69  #include <sys/machsystm.h>
  70   70  #include <sys/sysmacros.h>
  71   71  #include <sys/cpuvar.h>
  72   72  #include <sys/rm_platter.h>
  73   73  #include <sys/privregs.h>
  74   74  #include <sys/note.h>
  75   75  #include <sys/pci_intr_lib.h>
  76   76  #include <sys/spl.h>
  77   77  #include <sys/clock.h>
       78 +#include <sys/cyclic.h>
  78   79  #include <sys/dditypes.h>
  79   80  #include <sys/sunddi.h>
  80   81  #include <sys/x_call.h>
  81   82  #include <sys/reboot.h>
  82   83  #include <sys/mach_intr.h>
  83   84  #include <sys/apix.h>
  84   85  #include <sys/apix_irm_impl.h>
  85   86  
  86   87  static int apix_probe();
  87   88  static void apix_init();
↓ open down ↓ 977 lines elided ↑ open up ↑
1065 1066  /*
1066 1067   * If this module needs a periodic handler for the interrupt distribution, it
1067 1068   * can be added here. The argument to the periodic handler is not currently
1068 1069   * used, but is reserved for future.
1069 1070   */
1070 1071  static void
1071 1072  apix_post_cyclic_setup(void *arg)
1072 1073  {
1073 1074          UNREFERENCED_1PARAMETER(arg);
1074 1075  
     1076 +        cyc_handler_t cyh;
     1077 +        cyc_time_t cyt;
     1078 +
1075 1079          /* cpu_lock is held */
1076 1080          /* set up a periodic handler for intr redistribution */
1077 1081  
1078 1082          /*
1079 1083           * In peridoc mode intr redistribution processing is done in
1080 1084           * apic_intr_enter during clk intr processing
1081 1085           */
1082 1086          if (!apic_oneshot)
1083 1087                  return;
1084 1088  
1085 1089          /*
1086 1090           * Register a periodical handler for the redistribution processing.
1087      -         * On X86, CY_LOW_LEVEL is mapped to the level 2 interrupt, so
1088      -         * DDI_IPL_2 should be passed to ddi_periodic_add() here.
     1091 +         * Though we would generally prefer to use the DDI interface for
     1092 +         * periodic handler invocation, ddi_periodic_add(9F), we are
     1093 +         * unfortunately already holding cpu_lock, which ddi_periodic_add will
     1094 +         * attempt to take for us.  Thus, we add our own cyclic directly:
1089 1095           */
1090      -        apic_periodic_id = ddi_periodic_add(
1091      -            (void (*)(void *))apix_redistribute_compute, NULL,
1092      -            apic_redistribute_sample_interval, DDI_IPL_2);
     1096 +        cyh.cyh_func = (void (*)(void *))apix_redistribute_compute;
     1097 +        cyh.cyh_arg = NULL;
     1098 +        cyh.cyh_level = CY_LOW_LEVEL;
     1099 +
     1100 +        cyt.cyt_when = 0;
     1101 +        cyt.cyt_interval = apic_redistribute_sample_interval;
     1102 +
     1103 +        apic_cyclic_id = cyclic_add(&cyh, &cyt);
1093 1104  }
1094 1105  
1095 1106  /*
1096 1107   * Called the first time we enable x2apic mode on this cpu.
1097 1108   * Update some of the function pointers to use x2apic routines.
1098 1109   */
1099 1110  void
1100 1111  x2apic_update_psm()
1101 1112  {
1102 1113          struct psm_ops *pops = &apix_ops;
↓ open down ↓ 1454 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX