decay qos ost/oss penalties if MDS is not creating objects
i=nathan
i=johann
struct lov_qos_oss {
struct obd_uuid lqo_uuid; /* ptlrpc's c_remote_uuid */
struct list_head lqo_oss_list; /* link to lov_qos */
struct lov_qos_oss {
struct obd_uuid lqo_uuid; /* ptlrpc's c_remote_uuid */
struct list_head lqo_oss_list; /* link to lov_qos */
- __u32 lqo_ost_count; /* number of osts on this oss */
__u64 lqo_bavail; /* total bytes avail on OSS */
__u64 lqo_penalty; /* current penalty */
__u64 lqo_penalty_per_obj; /* penalty decrease every obj*/
__u64 lqo_bavail; /* total bytes avail on OSS */
__u64 lqo_penalty; /* current penalty */
__u64 lqo_penalty_per_obj; /* penalty decrease every obj*/
+ time_t lqo_used; /* last used time, seconds */
+ __u32 lqo_ost_count; /* number of osts on this oss */
__u64 ltq_penalty; /* current penalty */
__u64 ltq_penalty_per_obj; /* penalty decrease every obj*/
__u64 ltq_weight; /* net weighting */
__u64 ltq_penalty; /* current penalty */
__u64 ltq_penalty_per_obj; /* penalty decrease every obj*/
__u64 ltq_weight; /* net weighting */
+ time_t ltq_used; /* last used time, seconds */
unsigned int ltq_usable:1; /* usable for striping */
};
unsigned int ltq_usable:1; /* usable for striping */
};
__u64 ba_max, ba_min, temp;
__u32 num_active;
int rc, i, prio_wide;
__u64 ba_max, ba_min, temp;
__u32 num_active;
int rc, i, prio_wide;
ENTRY;
if (!lov->lov_qos.lq_dirty)
ENTRY;
if (!lov->lov_qos.lq_dirty)
ba_min = (__u64)(-1);
ba_max = 0;
ba_min = (__u64)(-1);
ba_max = 0;
+ now = cfs_time_current_sec();
/* Calculate OST penalty per object */
/* (lov ref taken in alloc_qos) */
for (i = 0; i < lov->desc.ld_tgt_count; i++) {
/* Calculate OST penalty per object */
/* (lov ref taken in alloc_qos) */
for (i = 0; i < lov->desc.ld_tgt_count; i++) {
lov->lov_tgts[i]->ltd_qos.ltq_penalty_per_obj =
(temp * prio_wide) >> 8;
lov->lov_tgts[i]->ltd_qos.ltq_penalty_per_obj =
(temp * prio_wide) >> 8;
- if (lov->lov_qos.lq_reset == 0)
+ age = (now - lov->lov_tgts[i]->ltd_qos.ltq_used) >> 3;
+ if (lov->lov_qos.lq_reset || age > 32 * lov->desc.ld_qos_maxage)
lov->lov_tgts[i]->ltd_qos.ltq_penalty = 0;
lov->lov_tgts[i]->ltd_qos.ltq_penalty = 0;
+ else if (age > lov->desc.ld_qos_maxage)
+ /* Decay the penalty by half for every 8x the update
+ * interval that the device has been idle. That gives
+ * lots of time for the statfs information to be
+ * updated (which the penalty is only a proxy for),
+ * and avoids penalizing OSS/OSTs under light load. */
+ lov->lov_tgts[i]->ltd_qos.ltq_penalty >>=
+ (age / lov->desc.ld_qos_maxage);
}
num_active = lov->lov_qos.lq_active_oss_count - 1;
}
num_active = lov->lov_qos.lq_active_oss_count - 1;
temp = oss->lqo_bavail >> 1;
do_div(temp, oss->lqo_ost_count * num_active);
oss->lqo_penalty_per_obj = (temp * prio_wide) >> 8;
temp = oss->lqo_bavail >> 1;
do_div(temp, oss->lqo_ost_count * num_active);
oss->lqo_penalty_per_obj = (temp * prio_wide) >> 8;
- if (lov->lov_qos.lq_reset == 0)
+
+ age = (now - oss->lqo_used) >> 3;
+ if (lov->lov_qos.lq_reset || age > 32 * lov->desc.ld_qos_maxage)
+ else if (age > lov->desc.ld_qos_maxage)
+ /* Decay the penalty by half for every 8x the update
+ * interval that the device has been idle. That gives
+ * lots of time for the statfs information to be
+ * updated (which the penalty is only a proxy for),
+ * and avoids penalizing OSS/OSTs under light load. */
+ oss->lqo_penalty >>= (age / lov->desc.ld_qos_maxage);
}
lov->lov_qos.lq_dirty = 0;
}
lov->lov_qos.lq_dirty = 0;
/* Difference is less than 20% */
lov->lov_qos.lq_same_space = 1;
/* Reset weights for the next time we enter qos mode */
/* Difference is less than 20% */
lov->lov_qos.lq_same_space = 1;
/* Reset weights for the next time we enter qos mode */
- lov->lov_qos.lq_reset = 0;
+ lov->lov_qos.lq_reset = 1;
lov->lov_tgts[index]->ltd_qos.ltq_penalty >>= 1;
oss->lqo_penalty >>= 1;
lov->lov_tgts[index]->ltd_qos.ltq_penalty >>= 1;
oss->lqo_penalty >>= 1;
+ /* mark the OSS and OST as recently used */
+ lov->lov_tgts[index]->ltd_qos.ltq_used =
+ oss->lqo_used = cfs_time_current_sec();
+
/* Set max penalties for this OST and OSS */
lov->lov_tgts[index]->ltd_qos.ltq_penalty +=
lov->lov_tgts[index]->ltd_qos.ltq_penalty_per_obj *
/* Set max penalties for this OST and OSS */
lov->lov_tgts[index]->ltd_qos.ltq_penalty +=
lov->lov_tgts[index]->ltd_qos.ltq_penalty_per_obj *
__swab32s (&ld->ld_tgt_count);
__swab32s (&ld->ld_active_tgt_count);
__swab32s (&ld->ld_default_stripe_count);
__swab32s (&ld->ld_tgt_count);
__swab32s (&ld->ld_active_tgt_count);
__swab32s (&ld->ld_default_stripe_count);
+ __swab32s (&ld->ld_pattern);
__swab64s (&ld->ld_default_stripe_size);
__swab64s (&ld->ld_default_stripe_offset);
__swab64s (&ld->ld_default_stripe_size);
__swab64s (&ld->ld_default_stripe_offset);
- __swab32s (&ld->ld_pattern);
__swab32s (&ld->ld_qos_maxage);
/* uuid endian insensitive */
}
__swab32s (&ld->ld_qos_maxage);
/* uuid endian insensitive */
}