mirror of
https://github.com/torvalds/linux.git
synced 2024-12-06 11:01:43 +00:00
rc80211-pid: export tuning parameters through debugfs
This adds all the tunable parameters used by rc80211_pid to debugfs for easy testing and tuning. Signed-off-by: Mattias Nissler <mattias.nissler@gmx.de> Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
12446c67fe
commit
1946b74ce0
@ -119,6 +119,20 @@ struct rc_pid_events_file_info {
|
|||||||
unsigned int next_entry;
|
unsigned int next_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct rc_pid_debugfs_entries {
|
||||||
|
struct dentry *dir;
|
||||||
|
struct dentry *target;
|
||||||
|
struct dentry *sampling_period;
|
||||||
|
struct dentry *coeff_p;
|
||||||
|
struct dentry *coeff_i;
|
||||||
|
struct dentry *coeff_d;
|
||||||
|
struct dentry *smoothing_shift;
|
||||||
|
struct dentry *sharpen_factor;
|
||||||
|
struct dentry *sharpen_duration;
|
||||||
|
struct dentry *norm_offset;
|
||||||
|
struct dentry *fast_start;
|
||||||
|
};
|
||||||
|
|
||||||
void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
|
void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
|
||||||
struct ieee80211_tx_status *stat);
|
struct ieee80211_tx_status *stat);
|
||||||
|
|
||||||
@ -222,8 +236,8 @@ struct rc_pid_info {
|
|||||||
/* Exponential averaging shift. */
|
/* Exponential averaging shift. */
|
||||||
unsigned int smoothing_shift;
|
unsigned int smoothing_shift;
|
||||||
|
|
||||||
/* Sharpening shift and duration. */
|
/* Sharpening factor and duration. */
|
||||||
unsigned int sharpen_shift;
|
unsigned int sharpen_factor;
|
||||||
unsigned int sharpen_duration;
|
unsigned int sharpen_duration;
|
||||||
|
|
||||||
/* Normalization offset. */
|
/* Normalization offset. */
|
||||||
@ -237,6 +251,11 @@ struct rc_pid_info {
|
|||||||
|
|
||||||
/* Index of the last used rate. */
|
/* Index of the last used rate. */
|
||||||
int oldrate;
|
int oldrate;
|
||||||
|
|
||||||
|
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||||
|
/* Debugfs entries created for the parameters above. */
|
||||||
|
struct rc_pid_debugfs_entries dentries;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* RC80211_PID_H */
|
#endif /* RC80211_PID_H */
|
||||||
|
@ -139,19 +139,20 @@ static void rate_control_pid_adjust_rate(struct ieee80211_local *local,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Normalize the failed frames per-rate differences. */
|
/* Normalize the failed frames per-rate differences. */
|
||||||
static void rate_control_pid_normalize(struct rc_pid_rateinfo *r, int l)
|
static void rate_control_pid_normalize(struct rc_pid_info *pinfo, int l)
|
||||||
{
|
{
|
||||||
int i;
|
int i, norm_offset = pinfo->norm_offset;
|
||||||
|
struct rc_pid_rateinfo *r = pinfo->rinfo;
|
||||||
|
|
||||||
if (r[0].diff > RC_PID_NORM_OFFSET)
|
if (r[0].diff > norm_offset)
|
||||||
r[0].diff -= RC_PID_NORM_OFFSET;
|
r[0].diff -= norm_offset;
|
||||||
else if (r[0].diff < -RC_PID_NORM_OFFSET)
|
else if (r[0].diff < -norm_offset)
|
||||||
r[0].diff += RC_PID_NORM_OFFSET;
|
r[0].diff += norm_offset;
|
||||||
for (i = 0; i < l - 1; i++)
|
for (i = 0; i < l - 1; i++)
|
||||||
if (r[i + 1].diff > r[i].diff + RC_PID_NORM_OFFSET)
|
if (r[i + 1].diff > r[i].diff + norm_offset)
|
||||||
r[i + 1].diff -= RC_PID_NORM_OFFSET;
|
r[i + 1].diff -= norm_offset;
|
||||||
else if (r[i + 1].diff <= r[i].diff)
|
else if (r[i + 1].diff <= r[i].diff)
|
||||||
r[i + 1].diff += RC_PID_NORM_OFFSET;
|
r[i + 1].diff += norm_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rate_control_pid_sample(struct rc_pid_info *pinfo,
|
static void rate_control_pid_sample(struct rc_pid_info *pinfo,
|
||||||
@ -163,18 +164,22 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
|
|||||||
struct ieee80211_hw_mode *mode;
|
struct ieee80211_hw_mode *mode;
|
||||||
u32 pf;
|
u32 pf;
|
||||||
s32 err_avg;
|
s32 err_avg;
|
||||||
s32 err_prop;
|
u32 err_prop;
|
||||||
s32 err_int;
|
u32 err_int;
|
||||||
s32 err_der;
|
u32 err_der;
|
||||||
int adj, i, j, tmp;
|
int adj, i, j, tmp;
|
||||||
|
unsigned long period;
|
||||||
|
|
||||||
mode = local->oper_hw_mode;
|
mode = local->oper_hw_mode;
|
||||||
spinfo = sta->rate_ctrl_priv;
|
spinfo = sta->rate_ctrl_priv;
|
||||||
|
|
||||||
/* In case nothing happened during the previous control interval, turn
|
/* In case nothing happened during the previous control interval, turn
|
||||||
* the sharpening factor on. */
|
* the sharpening factor on. */
|
||||||
if (jiffies - spinfo->last_sample > 2 * RC_PID_INTERVAL)
|
period = (HZ * pinfo->sampling_period + 500) / 1000;
|
||||||
spinfo->sharp_cnt = RC_PID_SHARPENING_DURATION;
|
if (!period)
|
||||||
|
period = 1;
|
||||||
|
if (jiffies - spinfo->last_sample > 2 * period)
|
||||||
|
spinfo->sharp_cnt = pinfo->sharpen_duration;
|
||||||
|
|
||||||
spinfo->last_sample = jiffies;
|
spinfo->last_sample = jiffies;
|
||||||
|
|
||||||
@ -202,17 +207,17 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
|
|||||||
rinfo[j].diff = rinfo[i].diff + tmp;
|
rinfo[j].diff = rinfo[i].diff + tmp;
|
||||||
pinfo->oldrate = sta->txrate;
|
pinfo->oldrate = sta->txrate;
|
||||||
}
|
}
|
||||||
rate_control_pid_normalize(rinfo, mode->num_rates);
|
rate_control_pid_normalize(pinfo, mode->num_rates);
|
||||||
|
|
||||||
/* Compute the proportional, integral and derivative errors. */
|
/* Compute the proportional, integral and derivative errors. */
|
||||||
err_prop = RC_PID_TARGET_PF - pf;
|
err_prop = pinfo->target - pf;
|
||||||
|
|
||||||
err_avg = spinfo->err_avg_sc >> RC_PID_SMOOTHING_SHIFT;
|
err_avg = spinfo->err_avg_sc >> pinfo->smoothing_shift;
|
||||||
spinfo->err_avg_sc = spinfo->err_avg_sc - err_avg + err_prop;
|
spinfo->err_avg_sc = spinfo->err_avg_sc - err_avg + err_prop;
|
||||||
err_int = spinfo->err_avg_sc >> RC_PID_SMOOTHING_SHIFT;
|
err_int = spinfo->err_avg_sc >> pinfo->smoothing_shift;
|
||||||
|
|
||||||
err_der = pf - spinfo->last_pf
|
err_der = (pf - spinfo->last_pf) *
|
||||||
* (1 + RC_PID_SHARPENING_FACTOR * spinfo->sharp_cnt);
|
(1 + pinfo->sharpen_factor * spinfo->sharp_cnt);
|
||||||
spinfo->last_pf = pf;
|
spinfo->last_pf = pf;
|
||||||
if (spinfo->sharp_cnt)
|
if (spinfo->sharp_cnt)
|
||||||
spinfo->sharp_cnt--;
|
spinfo->sharp_cnt--;
|
||||||
@ -241,6 +246,7 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
|
|||||||
struct rc_pid_info *pinfo = priv;
|
struct rc_pid_info *pinfo = priv;
|
||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
struct rc_pid_sta_info *spinfo;
|
struct rc_pid_sta_info *spinfo;
|
||||||
|
unsigned long period;
|
||||||
|
|
||||||
sta = sta_info_get(local, hdr->addr1);
|
sta = sta_info_get(local, hdr->addr1);
|
||||||
|
|
||||||
@ -285,7 +291,10 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
|
|||||||
sta->tx_num_mpdu_fail += status->retry_count;
|
sta->tx_num_mpdu_fail += status->retry_count;
|
||||||
|
|
||||||
/* Update PID controller state. */
|
/* Update PID controller state. */
|
||||||
if (time_after(jiffies, spinfo->last_sample + RC_PID_INTERVAL))
|
period = (HZ * pinfo->sampling_period + 500) / 1000;
|
||||||
|
if (!period)
|
||||||
|
period = 1;
|
||||||
|
if (time_after(jiffies, spinfo->last_sample + period))
|
||||||
rate_control_pid_sample(pinfo, local, sta);
|
rate_control_pid_sample(pinfo, local, sta);
|
||||||
|
|
||||||
sta_info_put(sta);
|
sta_info_put(sta);
|
||||||
@ -343,6 +352,9 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
|
|||||||
struct ieee80211_hw_mode *mode;
|
struct ieee80211_hw_mode *mode;
|
||||||
int i, j, tmp;
|
int i, j, tmp;
|
||||||
bool s;
|
bool s;
|
||||||
|
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||||
|
struct rc_pid_debugfs_entries *de;
|
||||||
|
#endif
|
||||||
|
|
||||||
pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
|
pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
|
||||||
if (!pinfo)
|
if (!pinfo)
|
||||||
@ -363,10 +375,10 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
|
|||||||
for (i = 0; i < mode->num_rates; i++) {
|
for (i = 0; i < mode->num_rates; i++) {
|
||||||
rinfo[i].index = i;
|
rinfo[i].index = i;
|
||||||
rinfo[i].rev_index = i;
|
rinfo[i].rev_index = i;
|
||||||
if (RC_PID_FAST_START)
|
if (pinfo->fast_start)
|
||||||
rinfo[i].diff = 0;
|
rinfo[i].diff = 0;
|
||||||
else
|
else
|
||||||
rinfo[i].diff = i * RC_PID_NORM_OFFSET;
|
rinfo[i].diff = i * pinfo->norm_offset;
|
||||||
}
|
}
|
||||||
for (i = 1; i < mode->num_rates; i++) {
|
for (i = 1; i < mode->num_rates; i++) {
|
||||||
s = 0;
|
s = 0;
|
||||||
@ -385,18 +397,72 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pinfo->target = RC_PID_TARGET_PF;
|
pinfo->target = RC_PID_TARGET_PF;
|
||||||
|
pinfo->sampling_period = RC_PID_INTERVAL;
|
||||||
pinfo->coeff_p = RC_PID_COEFF_P;
|
pinfo->coeff_p = RC_PID_COEFF_P;
|
||||||
pinfo->coeff_i = RC_PID_COEFF_I;
|
pinfo->coeff_i = RC_PID_COEFF_I;
|
||||||
pinfo->coeff_d = RC_PID_COEFF_D;
|
pinfo->coeff_d = RC_PID_COEFF_D;
|
||||||
|
pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT;
|
||||||
|
pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR;
|
||||||
|
pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION;
|
||||||
|
pinfo->norm_offset = RC_PID_NORM_OFFSET;
|
||||||
|
pinfo->fast_start = RC_PID_FAST_START;
|
||||||
pinfo->rinfo = rinfo;
|
pinfo->rinfo = rinfo;
|
||||||
pinfo->oldrate = 0;
|
pinfo->oldrate = 0;
|
||||||
|
|
||||||
|
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||||
|
de = &pinfo->dentries;
|
||||||
|
de->dir = debugfs_create_dir("rc80211_pid",
|
||||||
|
local->hw.wiphy->debugfsdir);
|
||||||
|
de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR,
|
||||||
|
de->dir, &pinfo->target);
|
||||||
|
de->sampling_period = debugfs_create_u32("sampling_period",
|
||||||
|
S_IRUSR | S_IWUSR, de->dir,
|
||||||
|
&pinfo->sampling_period);
|
||||||
|
de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR,
|
||||||
|
de->dir, &pinfo->coeff_p);
|
||||||
|
de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR,
|
||||||
|
de->dir, &pinfo->coeff_i);
|
||||||
|
de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR,
|
||||||
|
de->dir, &pinfo->coeff_d);
|
||||||
|
de->smoothing_shift = debugfs_create_u32("smoothing_shift",
|
||||||
|
S_IRUSR | S_IWUSR, de->dir,
|
||||||
|
&pinfo->smoothing_shift);
|
||||||
|
de->sharpen_factor = debugfs_create_u32("sharpen_factor",
|
||||||
|
S_IRUSR | S_IWUSR, de->dir,
|
||||||
|
&pinfo->sharpen_factor);
|
||||||
|
de->sharpen_duration = debugfs_create_u32("sharpen_duration",
|
||||||
|
S_IRUSR | S_IWUSR, de->dir,
|
||||||
|
&pinfo->sharpen_duration);
|
||||||
|
de->norm_offset = debugfs_create_u32("norm_offset",
|
||||||
|
S_IRUSR | S_IWUSR, de->dir,
|
||||||
|
&pinfo->norm_offset);
|
||||||
|
de->fast_start = debugfs_create_bool("fast_start",
|
||||||
|
S_IRUSR | S_IWUSR, de->dir,
|
||||||
|
&pinfo->fast_start);
|
||||||
|
#endif
|
||||||
|
|
||||||
return pinfo;
|
return pinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rate_control_pid_free(void *priv)
|
static void rate_control_pid_free(void *priv)
|
||||||
{
|
{
|
||||||
struct rc_pid_info *pinfo = priv;
|
struct rc_pid_info *pinfo = priv;
|
||||||
|
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||||
|
struct rc_pid_debugfs_entries *de = &pinfo->dentries;
|
||||||
|
|
||||||
|
debugfs_remove(de->fast_start);
|
||||||
|
debugfs_remove(de->norm_offset);
|
||||||
|
debugfs_remove(de->sharpen_duration);
|
||||||
|
debugfs_remove(de->sharpen_factor);
|
||||||
|
debugfs_remove(de->smoothing_shift);
|
||||||
|
debugfs_remove(de->coeff_d);
|
||||||
|
debugfs_remove(de->coeff_i);
|
||||||
|
debugfs_remove(de->coeff_p);
|
||||||
|
debugfs_remove(de->sampling_period);
|
||||||
|
debugfs_remove(de->target);
|
||||||
|
debugfs_remove(de->dir);
|
||||||
|
#endif
|
||||||
|
|
||||||
kfree(pinfo->rinfo);
|
kfree(pinfo->rinfo);
|
||||||
kfree(pinfo);
|
kfree(pinfo);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user