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

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/sys/ddi_timer.h
          +++ new/usr/src/uts/common/sys/ddi_timer.h
↓ open down ↓ 15 lines elided ↑ open up ↑
  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 2009 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
       26 +/*
       27 + * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
       28 + */
  26   29  
  27   30  #ifndef _SYS_DDI_TIMER_H
  28   31  #define _SYS_DDI_TIMER_H
  29   32  
  30   33  #include <sys/list.h>
       34 +#include <sys/taskq_impl.h>
       35 +#include <sys/cyclic.h>
  31   36  
  32   37  #ifdef  __cplusplus
  33   38  extern "C" {
  34   39  #endif
  35   40  
  36   41  #ifdef _KERNEL
  37   42  
  38   43  /*
  39   44   * Used by the new timeout functions
  40   45   */
  41   46  typedef struct __timeout *timeout_t;
  42   47  
  43      -/*
  44      - * Forward declarations.
  45      - */
  46      -struct cyc_timer;
  47      -struct tm_req;
       48 +typedef enum ddi_periodic_flags {
       49 +        DPF_DISPATCHED = 0x01,
       50 +        DPF_EXECUTING = 0x02,
       51 +        DPF_CANCELLED = 0x04
       52 +} ddi_periodic_flags_t;
  48   53  
  49      -/*
  50      - * Timing wheel cog.
  51      - * Each cog has a timeout request queue which is guarded by the lock
  52      - * here.
  53      - */
  54      -typedef struct timer_tw {
  55      -        list_t req;                     /* timeout request queue */
  56      -        kmutex_t lock;                  /* lock for this queue */
  57      -} timer_tw_t;
       54 +typedef struct ddi_periodic_impl {
       55 +        struct list_node dpr_link; /* protected by periodics_lock */
       56 +        struct list_node dpr_softint_link; /* only used when DPF_DISPATCHED */
       57 +        id_t dpr_id;
       58 +        hrtime_t dpr_interval;
  58   59  
  59      -/*
  60      - * Timer based on the cyclic subsystem.
  61      - * For each resolution, this timer structure should be allocated.
  62      - * Note. currently only one timer is used for periodic timeout requests,
  63      - * which is based on the system clock resolution.
  64      - */
  65      -typedef struct cyc_timer {
  66      -        hrtime_t res;                   /* this cyclic resolution */
  67      -        hrtime_t tick;                  /* tick of this cyclic */
  68      -        hrtime_t tick_time;             /* current time on this timer */
  69      -/*
  70      - * The hash size might need to be tuned if the lock contention is
  71      - * observed. So far the current size (1024) is sufficient though.
  72      - */
  73      -#define TM_HASH_SZ      (1024)          /* must be power of 2 */
  74      -#define TM_HASH(x)      ((x) & (TM_HASH_SZ -1))
  75      -        timer_tw_t idhash[TM_HASH_SZ];  /* ID hash */
  76      -        timer_tw_t exhash[TM_HASH_SZ];  /* expiration time hash */
  77      -} cyc_timer_t;
       60 +        kmutex_t dpr_lock;
       61 +        kcondvar_t dpr_cv;
       62 +        ddi_periodic_flags_t dpr_flags;
       63 +        uint_t dpr_level; /* 0 <= dpr_level <= 10 */
       64 +        taskq_ent_t dpr_taskq_ent; /* only used for level of 0 */
       65 +        uint64_t dpr_fire_count;
  78   66  
  79      -/*
  80      - * This value determines how many requests within 10ms can be allocated to
  81      - * different slots. This is an exponential number powered by 2.
  82      - * This value should be tuned with the hash size.
  83      - * Note. This value is fixed now, but can be adjusted by checking the number
  84      - * of CPUs when the timer structure is allocated.
  85      - */
  86      -#define TICK_FACTOR     (3)
       67 +        cyclic_id_t dpr_cyclic_id;
  87   68  
  88      -/*
  89      - * Timer request.
  90      - */
  91      -typedef struct tm_req {
  92      -        struct list_node id_req;        /* request on ID hash */
  93      -        struct list_node ex_req;        /* request on expire hash */
  94      -        struct list_node disp_req;      /* request on dispatch queue */
  95      -        hrtime_t interval;      /* interval this request needs */
  96      -        hrtime_t exp_time;      /* time when the request executes */
  97      -        void (*handler)(void *);        /* timeout handler */
  98      -        void *arg;              /* timeout argument */
  99      -        kthread_t *h_thread;    /* handler thread */
 100      -        kmutex_t lock;          /* lock for setting counter and flag */
 101      -        kcondvar_t cv;          /* condition variable against the lock */
 102      -        timeout_t id;           /* this request id */
 103      -        int level;              /* interrupt level */
 104      -        volatile uint_t flags;  /* flags passed to ddi_timeout() */
 105      -        /*
 106      -         * State flags
 107      -         * These are used internally.
 108      -         */
 109      -#define TM_INVOKING     0x00000001      /* cyclic is invoked now */
 110      -#define TM_EXECUTING    0x00000002      /* timeout is executed now */
 111      -#define TM_CANCEL       0x00000004      /* request is canceled */
 112      -#define TM_TRANSFER     0x00000008      /* request is transfered */
 113      -#define TM_UTMCOMP      0x00000040      /* untimeout is complete */
 114      -        uint_t cnt;             /* invoke counter */
 115      -} tm_req_t;
       69 +        void (*dpr_handler)(void *);
       70 +        void *dpr_arg;
       71 +} ddi_periodic_impl_t;
 116   72  
 117   73  /*
 118      - * Software interrupt intr_state:
 119      - *
 120      - *  31              16 15               0
 121      - * +------------------+------------------+
 122      - * |  interrupt start |  interrupt set   |
 123      - * +------------------+------------------+
 124      - *
 125      - * Note. This structure can accomodate interrupts up to the level 15,
 126      - * but supported interrupts are up to the level 10 in practice because
 127      - * of the ddi timer restriction.
       74 + * Internal implementation functions for the DDI periodic interface.
 128   75   */
 129      -#define TM_INTR_SET(l)          (1 << (l))
 130      -#define TM_INTR_START(l)        (1 << ((l) + 16))
 131      -
 132      -/*
 133      - * internal functions for the ddi timeout
 134      - */
 135      -void timer_init(void);
 136      -void cyclic_timer(void);
 137      -void timer_softintr(int);
       76 +void ddi_periodic_init(void);
       77 +void ddi_periodic_softintr(int level);
 138   78  timeout_t i_timeout(void (*)(void *), void *, hrtime_t, int);
 139   79  void i_untimeout(timeout_t);
 140   80  
 141   81  #endif  /* _KERNEL */
 142   82  
 143   83  #ifdef  __cplusplus
 144   84  }
 145   85  #endif
 146   86  
 147   87  #endif  /* _SYS_DDI_TIMER_H */
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX