linux/net/mac80211/rc80211_pid.h
<<
>>
Prefs
   1/*
   2 * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de>
   3 * Copyright 2007, Stefano Brivio <stefano.brivio@polimi.it>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 as
   7 * published by the Free Software Foundation.
   8 */
   9
  10#ifndef RC80211_PID_H
  11#define RC80211_PID_H
  12
  13/* Sampling period for measuring percentage of failed frames in ms. */
  14#define RC_PID_INTERVAL                 125
  15
  16/* Exponential averaging smoothness (used for I part of PID controller) */
  17#define RC_PID_SMOOTHING_SHIFT          3
  18#define RC_PID_SMOOTHING                (1 << RC_PID_SMOOTHING_SHIFT)
  19
  20/* Sharpening factor (used for D part of PID controller) */
  21#define RC_PID_SHARPENING_FACTOR        0
  22#define RC_PID_SHARPENING_DURATION      0
  23
  24/* Fixed point arithmetic shifting amount. */
  25#define RC_PID_ARITH_SHIFT              8
  26
  27/* Proportional PID component coefficient. */
  28#define RC_PID_COEFF_P                  15
  29/* Integral PID component coefficient. */
  30#define RC_PID_COEFF_I                  9
  31/* Derivative PID component coefficient. */
  32#define RC_PID_COEFF_D                  15
  33
  34/* Target failed frames rate for the PID controller. NB: This effectively gives
  35 * maximum failed frames percentage we're willing to accept. If the wireless
  36 * link quality is good, the controller will fail to adjust failed frames
  37 * percentage to the target. This is intentional.
  38 */
  39#define RC_PID_TARGET_PF                14
  40
  41/* Rate behaviour normalization quantity over time. */
  42#define RC_PID_NORM_OFFSET              3
  43
  44/* Push high rates right after loading. */
  45#define RC_PID_FAST_START               0
  46
  47/* Arithmetic right shift for positive and negative values for ISO C. */
  48#define RC_PID_DO_ARITH_RIGHT_SHIFT(x, y) \
  49        ((x) < 0 ? -((-(x)) >> (y)) : (x) >> (y))
  50
  51enum rc_pid_event_type {
  52        RC_PID_EVENT_TYPE_TX_STATUS,
  53        RC_PID_EVENT_TYPE_RATE_CHANGE,
  54        RC_PID_EVENT_TYPE_TX_RATE,
  55        RC_PID_EVENT_TYPE_PF_SAMPLE,
  56};
  57
  58union rc_pid_event_data {
  59        /* RC_PID_EVENT_TX_STATUS */
  60        struct {
  61                u32 flags;
  62                struct ieee80211_tx_info tx_status;
  63        };
  64        /* RC_PID_EVENT_TYPE_RATE_CHANGE */
  65        /* RC_PID_EVENT_TYPE_TX_RATE */
  66        struct {
  67                int index;
  68                int rate;
  69        };
  70        /* RC_PID_EVENT_TYPE_PF_SAMPLE */
  71        struct {
  72                s32 pf_sample;
  73                s32 prop_err;
  74                s32 int_err;
  75                s32 der_err;
  76        };
  77};
  78
  79struct rc_pid_event {
  80        /* The time when the event occurred */
  81        unsigned long timestamp;
  82
  83        /* Event ID number */
  84        unsigned int id;
  85
  86        /* Type of event */
  87        enum rc_pid_event_type type;
  88
  89        /* type specific data */
  90        union rc_pid_event_data data;
  91};
  92
  93/* Size of the event ring buffer. */
  94#define RC_PID_EVENT_RING_SIZE 32
  95
  96struct rc_pid_event_buffer {
  97        /* Counter that generates event IDs */
  98        unsigned int ev_count;
  99
 100        /* Ring buffer of events */
 101        struct rc_pid_event ring[RC_PID_EVENT_RING_SIZE];
 102
 103        /* Index to the entry in events_buf to be reused */
 104        unsigned int next_entry;
 105
 106        /* Lock that guards against concurrent access to this buffer struct */
 107        spinlock_t lock;
 108
 109        /* Wait queue for poll/select and blocking I/O */
 110        wait_queue_head_t waitqueue;
 111};
 112
 113struct rc_pid_events_file_info {
 114        /* The event buffer we read */
 115        struct rc_pid_event_buffer *events;
 116
 117        /* The entry we have should read next */
 118        unsigned int next_entry;
 119};
 120
 121/**
 122 * struct rc_pid_debugfs_entries - tunable parameters
 123 *
 124 * Algorithm parameters, tunable via debugfs.
 125 * @target: target percentage for failed frames
 126 * @sampling_period: error sampling interval in milliseconds
 127 * @coeff_p: absolute value of the proportional coefficient
 128 * @coeff_i: absolute value of the integral coefficient
 129 * @coeff_d: absolute value of the derivative coefficient
 130 * @smoothing_shift: absolute value of the integral smoothing factor (i.e.
 131 *      amount of smoothing introduced by the exponential moving average)
 132 * @sharpen_factor: absolute value of the derivative sharpening factor (i.e.
 133 *      amount of emphasis given to the derivative term after low activity
 134 *      events)
 135 * @sharpen_duration: duration of the sharpening effect after the detected low
 136 *      activity event, relative to sampling_period
 137 * @norm_offset: amount of normalization periodically performed on the learnt
 138 *      rate behaviour values (lower means we should trust more what we learnt
 139 *      about behaviour of rates, higher means we should trust more the natural
 140 *      ordering of rates)
 141 */
 142struct rc_pid_debugfs_entries {
 143        struct dentry *target;
 144        struct dentry *sampling_period;
 145        struct dentry *coeff_p;
 146        struct dentry *coeff_i;
 147        struct dentry *coeff_d;
 148        struct dentry *smoothing_shift;
 149        struct dentry *sharpen_factor;
 150        struct dentry *sharpen_duration;
 151        struct dentry *norm_offset;
 152};
 153
 154void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
 155                                      struct ieee80211_tx_info *stat);
 156
 157void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf,
 158                                               int index, int rate);
 159
 160void rate_control_pid_event_tx_rate(struct rc_pid_event_buffer *buf,
 161                                           int index, int rate);
 162
 163void rate_control_pid_event_pf_sample(struct rc_pid_event_buffer *buf,
 164                                             s32 pf_sample, s32 prop_err,
 165                                             s32 int_err, s32 der_err);
 166
 167void rate_control_pid_add_sta_debugfs(void *priv, void *priv_sta,
 168                                             struct dentry *dir);
 169
 170void rate_control_pid_remove_sta_debugfs(void *priv, void *priv_sta);
 171
 172struct rc_pid_sta_info {
 173        unsigned long last_change;
 174        unsigned long last_sample;
 175
 176        u32 tx_num_failed;
 177        u32 tx_num_xmit;
 178
 179        int txrate_idx;
 180
 181        /* Average failed frames percentage error (i.e. actual vs. target
 182         * percentage), scaled by RC_PID_SMOOTHING. This value is computed
 183         * using using an exponential weighted average technique:
 184         *
 185         *           (RC_PID_SMOOTHING - 1) * err_avg_old + err
 186         * err_avg = ------------------------------------------
 187         *                       RC_PID_SMOOTHING
 188         *
 189         * where err_avg is the new approximation, err_avg_old the previous one
 190         * and err is the error w.r.t. to the current failed frames percentage
 191         * sample. Note that the bigger RC_PID_SMOOTHING the more weight is
 192         * given to the previous estimate, resulting in smoother behavior (i.e.
 193         * corresponding to a longer integration window).
 194         *
 195         * For computation, we actually don't use the above formula, but this
 196         * one:
 197         *
 198         * err_avg_scaled = err_avg_old_scaled - err_avg_old + err
 199         *
 200         * where:
 201         *      err_avg_scaled = err * RC_PID_SMOOTHING
 202         *      err_avg_old_scaled = err_avg_old * RC_PID_SMOOTHING
 203         *
 204         * This avoids floating point numbers and the per_failed_old value can
 205         * easily be obtained by shifting per_failed_old_scaled right by
 206         * RC_PID_SMOOTHING_SHIFT.
 207         */
 208        s32 err_avg_sc;
 209
 210        /* Last framed failes percentage sample. */
 211        u32 last_pf;
 212
 213        /* Sharpening needed. */
 214        u8 sharp_cnt;
 215
 216#ifdef CONFIG_MAC80211_DEBUGFS
 217        /* Event buffer */
 218        struct rc_pid_event_buffer events;
 219
 220        /* Events debugfs file entry */
 221        struct dentry *events_entry;
 222#endif
 223};
 224
 225/* Algorithm parameters. We keep them on a per-algorithm approach, so they can
 226 * be tuned individually for each interface.
 227 */
 228struct rc_pid_rateinfo {
 229
 230        /* Map sorted rates to rates in ieee80211_hw_mode. */
 231        int index;
 232
 233        /* Map rates in ieee80211_hw_mode to sorted rates. */
 234        int rev_index;
 235
 236        /* Did we do any measurement on this rate? */
 237        bool valid;
 238
 239        /* Comparison with the lowest rate. */
 240        int diff;
 241};
 242
 243struct rc_pid_info {
 244
 245        /* The failed frames percentage target. */
 246        unsigned int target;
 247
 248        /* Rate at which failed frames percentage is sampled in 0.001s. */
 249        unsigned int sampling_period;
 250
 251        /* P, I and D coefficients. */
 252        int coeff_p;
 253        int coeff_i;
 254        int coeff_d;
 255
 256        /* Exponential averaging shift. */
 257        unsigned int smoothing_shift;
 258
 259        /* Sharpening factor and duration. */
 260        unsigned int sharpen_factor;
 261        unsigned int sharpen_duration;
 262
 263        /* Normalization offset. */
 264        unsigned int norm_offset;
 265
 266        /* Rates information. */
 267        struct rc_pid_rateinfo *rinfo;
 268
 269        /* Index of the last used rate. */
 270        int oldrate;
 271
 272#ifdef CONFIG_MAC80211_DEBUGFS
 273        /* Debugfs entries created for the parameters above. */
 274        struct rc_pid_debugfs_entries dentries;
 275#endif
 276};
 277
 278#endif /* RC80211_PID_H */
 279
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.