struct lu_tgt_pool *osts;
struct lu_qos_rr *lqr;
unsigned int i, array_idx;
- __u32 ost_start_idx_temp;
__u32 stripe_idx = 0;
__u32 stripe_count, stripe_count_min, ost_idx;
int rc, speed = 0, ost_connecting = 0;
down_read(&m->lod_ost_descs.ltd_qos.lq_rw_sem);
spin_lock(&lqr->lqr_alloc);
if (--lqr->lqr_start_count <= 0) {
- lqr->lqr_start_idx = prandom_u32_max(osts->op_count);
+ atomic_set(&lqr->lqr_start_idx,
+ prandom_u32_max(osts->op_count));
lqr->lqr_start_count =
(LOV_CREATE_RESEED_MIN / max(osts->op_count, 1U) +
LOV_CREATE_RESEED_MULT) * max(osts->op_count, 1U);
- } else if (stripe_count_min >= osts->op_count ||
- lqr->lqr_start_idx > osts->op_count) {
- /* If we have allocated from all of the OSTs, slowly
- * precess the next start if the OST/stripe count isn't
- * already doing this for us. */
- lqr->lqr_start_idx %= osts->op_count;
+ } else if (atomic_read(&lqr->lqr_start_idx) >= osts->op_count) {
+ /* If we have allocated from all of the tgts, slowly
+ * precess the next start OST if the tgt/stripe count
+ * difference isn't already doing this for us.
+ */
+ atomic_sub(osts->op_count, &lqr->lqr_start_idx);
if (stripe_count > 1 && (osts->op_count % stripe_count) != 1)
++lqr->lqr_offset_idx;
}
- ost_start_idx_temp = lqr->lqr_start_idx;
+ spin_unlock(&lqr->lqr_alloc);
+ if (lod_comp->llc_pattern & LOV_PATTERN_OVERSTRIPING)
+ stripes_per_ost =
+ (lod_comp->llc_stripe_count - 1) / osts->op_count + 1;
repeat_find:
-
QOS_DEBUG("pool '%s' want %d start_idx %d start_count %d offset %d "
"active %d count %d\n",
lod_comp->llc_pool ? lod_comp->llc_pool : "",
- stripe_count, lqr->lqr_start_idx, lqr->lqr_start_count,
- lqr->lqr_offset_idx, osts->op_count, osts->op_count);
+ stripe_count, atomic_read(&lqr->lqr_start_idx),
+ lqr->lqr_start_count, lqr->lqr_offset_idx, osts->op_count,
+ osts->op_count);
- if (lod_comp->llc_pattern & LOV_PATTERN_OVERSTRIPING)
- stripes_per_ost =
- (lod_comp->llc_stripe_count - 1)/osts->op_count + 1;
+ for (i = 0; i < osts->op_count * stripes_per_ost &&
+ stripe_idx < stripe_count; i++) {
+ int idx;
- for (i = 0; i < osts->op_count * stripes_per_ost
- && stripe_idx < stripe_count; i++) {
- array_idx = (lqr->lqr_start_idx + lqr->lqr_offset_idx) %
+ idx = atomic_inc_return(&lqr->lqr_start_idx);
+ array_idx = (idx + lqr->lqr_offset_idx) %
osts->op_count;
- ++lqr->lqr_start_idx;
ost_idx = lqr->lqr_pool.op_array[array_idx];
QOS_DEBUG("#%d strt %d act %d strp %d ary %d idx %d\n",
- i, lqr->lqr_start_idx, /* XXX: active*/ 0,
+ i, idx, /* XXX: active*/ 0,
stripe_idx, array_idx, ost_idx);
if ((ost_idx == LOV_QOS_EMPTY) ||
if (OBD_FAIL_CHECK(OBD_FAIL_MDS_OSC_PRECREATE) && ost_idx == 0)
continue;
- spin_unlock(&lqr->lqr_alloc);
rc = lod_check_and_reserve_ost(env, lo, lod_comp, ost_idx,
speed, &stripe_idx, stripe,
ost_indices, th, &overstriped,
reserve);
- spin_lock(&lqr->lqr_alloc);
if (rc != 0 && OST_TGT(m, ost_idx)->ltd_connecting)
ost_connecting = 1;
if ((speed < 2) && (stripe_idx < stripe_count_min)) {
/* Try again, allowing slower OSCs */
speed++;
- lqr->lqr_start_idx = ost_start_idx_temp;
ost_connecting = 0;
goto repeat_find;
}
-
- spin_unlock(&lqr->lqr_alloc);
up_read(&m->lod_ost_descs.ltd_qos.lq_rw_sem);
/* If there are enough OSTs, a component with overstriping requested
unsigned int pool_idx;
unsigned int i;
u32 saved_idx = stripe_idx;
- u32 start_mdt;
u32 mdt_idx;
bool use_degraded = false;
int tgt_connecting = 0;
down_read(<d->ltd_qos.lq_rw_sem);
spin_lock(&lqr->lqr_alloc);
if (--lqr->lqr_start_count <= 0) {
- lqr->lqr_start_idx = prandom_u32_max(pool->op_count);
+ atomic_set(&lqr->lqr_start_idx,
+ prandom_u32_max(pool->op_count));
lqr->lqr_start_count =
(LOV_CREATE_RESEED_MIN / max(pool->op_count, 1U) +
LOV_CREATE_RESEED_MULT) * max(pool->op_count, 1U);
- } else if (stripe_count - 1 >= pool->op_count ||
- lqr->lqr_start_idx > pool->op_count) {
+ } else if (atomic_read(&lqr->lqr_start_idx) >= pool->op_count) {
/* If we have allocated from all of the tgts, slowly
* precess the next start if the tgt/stripe count isn't
* already doing this for us. */
- lqr->lqr_start_idx %= pool->op_count;
+ atomic_sub(pool->op_count, &lqr->lqr_start_idx);
if (stripe_count - 1 > 1 &&
(pool->op_count % (stripe_count - 1)) != 1)
++lqr->lqr_offset_idx;
}
- start_mdt = lqr->lqr_start_idx;
+ spin_unlock(&lqr->lqr_alloc);
repeat_find:
QOS_DEBUG("want=%d start_idx=%d start_count=%d offset=%d active=%d count=%d\n",
- stripe_count - 1, lqr->lqr_start_idx, lqr->lqr_start_count,
- lqr->lqr_offset_idx, pool->op_count, pool->op_count);
+ stripe_count - 1, atomic_read(&lqr->lqr_start_idx),
+ lqr->lqr_start_count, lqr->lqr_offset_idx, pool->op_count,
+ pool->op_count);
for (i = 0; i < pool->op_count && stripe_idx < stripe_count; i++) {
- pool_idx = (lqr->lqr_start_idx + lqr->lqr_offset_idx) %
+ int idx;
+
+ idx = atomic_inc_return(&lqr->lqr_start_idx);
+ pool_idx = (idx + lqr->lqr_offset_idx) %
pool->op_count;
- ++lqr->lqr_start_idx;
mdt_idx = lqr->lqr_pool.op_array[pool_idx];
mdt = LTD_TGT(ltd, mdt_idx);
QOS_DEBUG("#%d strt %d act %d strp %d ary %d idx %d\n",
- i, lqr->lqr_start_idx, /* XXX: active*/ 0,
+ i, idx, /* XXX: active*/ 0,
stripe_idx, pool_idx, mdt_idx);
if (mdt_idx == LOV_QOS_EMPTY ||
QOS_DEBUG("#%d: degraded\n", mdt_idx);
continue;
}
- spin_unlock(&lqr->lqr_alloc);
rc = dt_fid_alloc(env, mdt->ltd_tgt, &fid, NULL, NULL);
if (rc < 0) {
QOS_DEBUG("#%d: alloc FID failed: %dl\n", mdt_idx, rc);
- spin_lock(&lqr->lqr_alloc);
continue;
}
lo->ldo_obj.do_lu.lo_dev->ld_site->ls_top_dev,
&conf);
- spin_lock(&lqr->lqr_alloc);
if (IS_ERR(dto)) {
QOS_DEBUG("can't alloc stripe on #%u: %d\n",
mdt->ltd_index, (int) PTR_ERR(dto));
if (!use_degraded && stripe_idx < stripe_count) {
/* Try again, allowing slower MDTs */
use_degraded = true;
- lqr->lqr_start_idx = start_mdt;
tgt_connecting = 0;
goto repeat_find;
}
- spin_unlock(&lqr->lqr_alloc);
up_read(<d->ltd_qos.lq_rw_sem);
if (stripe_idx > saved_idx)