int count, int *eof, void *data)
{
struct ptlrpc_service *svc = data;
+ struct ptlrpc_service_part *svcpt;
+ int total = 0;
+ int i;
*eof = 1;
- return snprintf(page, count, "%d\n", svc->srv_part->scp_hist_nrqbds);
+
+ ptlrpc_service_for_each_part(svcpt, i, svc)
+ total += svcpt->scp_hist_nrqbds;
+
+ return snprintf(page, count, "%d\n", total);
}
static int
ptlrpc_lprocfs_read_req_history_max(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
- struct ptlrpc_service *svc = data;
+ struct ptlrpc_service *svc = data;
+ struct ptlrpc_service_part *svcpt;
+ int total = 0;
+ int i;
- *eof = 1;
- return snprintf(page, count, "%d\n", svc->srv_max_history_rqbds);
+ *eof = 1;
+ ptlrpc_service_for_each_part(svcpt, i, svc)
+ total += svc->srv_hist_nrqbds_cpt_max;
+
+ return snprintf(page, count, "%d\n", total);
}
static int
ptlrpc_lprocfs_write_req_history_max(struct file *file, const char *buffer,
unsigned long count, void *data)
{
- struct ptlrpc_service *svc = data;
- int bufpages;
- int val;
- int rc = lprocfs_write_helper(buffer, count, &val);
+ struct ptlrpc_service *svc = data;
+ int bufpages;
+ int val;
+ int rc;
+ rc = lprocfs_write_helper(buffer, count, &val);
if (rc < 0)
return rc;
return -ERANGE;
cfs_spin_lock(&svc->srv_lock);
- svc->srv_max_history_rqbds = val;
+
+ if (val == 0)
+ svc->srv_hist_nrqbds_cpt_max = 0;
+ else
+ svc->srv_hist_nrqbds_cpt_max = max(1, (val / svc->srv_ncpts));
+
cfs_spin_unlock(&svc->srv_lock);
return count;
static int
ptlrpc_lprocfs_rd_threads_min(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+ int count, int *eof, void *data)
{
- struct ptlrpc_service *svc = data;
+ struct ptlrpc_service *svc = data;
- return snprintf(page, count, "%d\n", svc->srv_threads_min);
+ return snprintf(page, count, "%d\n",
+ svc->srv_nthrs_cpt_init * svc->srv_ncpts);
}
static int
ptlrpc_lprocfs_wr_threads_min(struct file *file, const char *buffer,
unsigned long count, void *data)
{
- struct ptlrpc_service *svc = data;
- int val;
- int rc = lprocfs_write_helper(buffer, count, &val);
+ struct ptlrpc_service *svc = data;
+ int val;
+ int rc = lprocfs_write_helper(buffer, count, &val);
- if (rc < 0)
- return rc;
+ if (rc < 0)
+ return rc;
- if (val < 2)
- return -ERANGE;
+ if (val / svc->srv_ncpts < PTLRPC_NTHRS_INIT)
+ return -ERANGE;
cfs_spin_lock(&svc->srv_lock);
- if (val > svc->srv_threads_max) {
+ if (val > svc->srv_nthrs_cpt_limit * svc->srv_ncpts) {
cfs_spin_unlock(&svc->srv_lock);
return -ERANGE;
}
- svc->srv_threads_min = val;
+ svc->srv_nthrs_cpt_init = val / svc->srv_ncpts;
+
cfs_spin_unlock(&svc->srv_lock);
return count;
int count, int *eof, void *data)
{
struct ptlrpc_service *svc = data;
+ struct ptlrpc_service_part *svcpt;
+ int total = 0;
+ int i;
- LASSERT(svc->srv_part != NULL);
- return snprintf(page, count, "%d\n",
- svc->srv_part->scp_nthrs_running);
+ LASSERT(svc->srv_parts != NULL);
+ ptlrpc_service_for_each_part(svcpt, i, svc)
+ total += svcpt->scp_nthrs_running;
+
+ return snprintf(page, count, "%d\n", total);
}
static int
ptlrpc_lprocfs_rd_threads_max(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+ int count, int *eof, void *data)
{
- struct ptlrpc_service *svc = data;
+ struct ptlrpc_service *svc = data;
- return snprintf(page, count, "%d\n", svc->srv_threads_max);
+ return snprintf(page, count, "%d\n",
+ svc->srv_nthrs_cpt_limit * svc->srv_ncpts);
}
static int
ptlrpc_lprocfs_wr_threads_max(struct file *file, const char *buffer,
- unsigned long count, void *data)
+ unsigned long count, void *data)
{
- struct ptlrpc_service *svc = data;
- int val;
- int rc = lprocfs_write_helper(buffer, count, &val);
+ struct ptlrpc_service *svc = data;
+ int val;
+ int rc = lprocfs_write_helper(buffer, count, &val);
- if (rc < 0)
- return rc;
+ if (rc < 0)
+ return rc;
- if (val < 2)
- return -ERANGE;
+ if (val / svc->srv_ncpts < PTLRPC_NTHRS_INIT)
+ return -ERANGE;
cfs_spin_lock(&svc->srv_lock);
- if (val < svc->srv_threads_min) {
+ if (val < svc->srv_nthrs_cpt_init * svc->srv_ncpts) {
cfs_spin_unlock(&svc->srv_lock);
return -ERANGE;
}
- svc->srv_threads_max = val;
+ svc->srv_nthrs_cpt_limit = val / svc->srv_ncpts;
+
cfs_spin_unlock(&svc->srv_lock);
return count;
}
struct ptlrpc_srh_iterator {
- __u64 srhi_seq;
- struct ptlrpc_request *srhi_req;
+ int srhi_idx;
+ __u64 srhi_seq;
+ struct ptlrpc_request *srhi_req;
};
int
* be near the head), we shouldn't have to do long
* re-scans */
LASSERT (srhi->srhi_seq == srhi->srhi_req->rq_history_seq);
- LASSERT(!cfs_list_empty(&svcpt->scp_hist_reqs));
+ LASSERTF(!cfs_list_empty(&svcpt->scp_hist_reqs),
+ "%s:%d: seek offset "LPU64", request seq "LPU64", "
+ "last culled "LPU64"\n",
+ svcpt->scp_service->srv_name, svcpt->scp_cpt,
+ seq, srhi->srhi_seq, svcpt->scp_hist_seq_culled);
e = &srhi->srhi_req->rq_history_list;
} else {
/* search from start */
static void *
ptlrpc_lprocfs_svc_req_history_start(struct seq_file *s, loff_t *pos)
{
- struct ptlrpc_service *svc = s->private;
- struct ptlrpc_srh_iterator *srhi;
- int rc;
+ struct ptlrpc_service *svc = s->private;
+ struct ptlrpc_service_part *svcpt;
+ struct ptlrpc_srh_iterator *srhi;
+ int rc;
+ int i;
- OBD_ALLOC(srhi, sizeof(*srhi));
- if (srhi == NULL)
- return NULL;
+ OBD_ALLOC(srhi, sizeof(*srhi));
+ if (srhi == NULL)
+ return NULL;
- srhi->srhi_seq = 0;
- srhi->srhi_req = NULL;
+ srhi->srhi_seq = 0;
+ srhi->srhi_req = NULL;
- cfs_spin_lock(&svc->srv_part->scp_lock);
- rc = ptlrpc_lprocfs_svc_req_history_seek(svc->srv_part, srhi, *pos);
- cfs_spin_unlock(&svc->srv_part->scp_lock);
+ ptlrpc_service_for_each_part(svcpt, i, svc) {
+ srhi->srhi_idx = i;
- if (rc == 0) {
- *pos = srhi->srhi_seq;
- return srhi;
- }
+ cfs_spin_lock(&svcpt->scp_lock);
+ rc = ptlrpc_lprocfs_svc_req_history_seek(svcpt, srhi, *pos);
+ cfs_spin_unlock(&svcpt->scp_lock);
+ if (rc == 0) {
+ *pos = srhi->srhi_seq;
+ return srhi;
+ }
+ }
- OBD_FREE(srhi, sizeof(*srhi));
- return NULL;
+ OBD_FREE(srhi, sizeof(*srhi));
+ return NULL;
}
static void
void *iter, loff_t *pos)
{
struct ptlrpc_service *svc = s->private;
- struct ptlrpc_service_part *svcpt = svc->srv_part;
struct ptlrpc_srh_iterator *srhi = iter;
- int rc;
+ struct ptlrpc_service_part *svcpt;
+ int rc = 0;
+ int i;
- cfs_spin_lock(&svcpt->scp_lock);
- rc = ptlrpc_lprocfs_svc_req_history_seek(svcpt, srhi, *pos + 1);
- cfs_spin_unlock(&svcpt->scp_lock);
+ for (i = srhi->srhi_idx; i < svc->srv_ncpts; i++) {
+ svcpt = svc->srv_parts[i];
+
+ srhi->srhi_idx = i;
+
+ cfs_spin_lock(&svcpt->scp_lock);
+ rc = ptlrpc_lprocfs_svc_req_history_seek(svcpt, srhi, *pos + 1);
+ cfs_spin_unlock(&svcpt->scp_lock);
+ if (rc == 0)
+ break;
+ }
if (rc != 0) {
OBD_FREE(srhi, sizeof(*srhi));
static int ptlrpc_lprocfs_svc_req_history_show(struct seq_file *s, void *iter)
{
struct ptlrpc_service *svc = s->private;
- struct ptlrpc_service_part *svcpt = svc->srv_part;
struct ptlrpc_srh_iterator *srhi = iter;
+ struct ptlrpc_service_part *svcpt;
struct ptlrpc_request *req;
int rc;
+ LASSERT(srhi->srhi_idx < svc->srv_ncpts);
+
+ svcpt = svc->srv_parts[srhi->srhi_idx];
+
cfs_spin_lock(&svcpt->scp_lock);
rc = ptlrpc_lprocfs_svc_req_history_seek(svcpt, srhi, srhi->srhi_seq);
time_t worstt;
unsigned int cur;
unsigned int worst;
+ int nob = 0;
int rc = 0;
+ int i;
- svcpt = svc->srv_part;
- LASSERT(svcpt != NULL);
+ LASSERT(svc->srv_parts != NULL);
+
+ if (AT_OFF) {
+ rc += snprintf(page + rc, count - rc,
+ "adaptive timeouts off, using obd_timeout %u\n",
+ obd_timeout);
+ return rc;
+ }
+
+ ptlrpc_service_for_each_part(svcpt, i, svc) {
+ cur = at_get(&svcpt->scp_at_estimate);
+ worst = svcpt->scp_at_estimate.at_worst_ever;
+ worstt = svcpt->scp_at_estimate.at_worst_time;
+ s2dhms(&ts, cfs_time_current_sec() - worstt);
+
+ nob = snprintf(page, count,
+ "%10s : cur %3u worst %3u (at %ld, "
+ DHMS_FMT" ago) ", "service",
+ cur, worst, worstt, DHMS_VARS(&ts));
+
+ nob = lprocfs_at_hist_helper(page, count, nob,
+ &svcpt->scp_at_estimate);
+ rc += nob;
+ page += nob;
+ count -= nob;
+
+ /*
+ * NB: for lustre proc read, the read count must be less
+ * than PAGE_SIZE, please see details in lprocfs_fops_read.
+ * It's unlikely that we exceed PAGE_SIZE at here because
+ * it means the service has more than 50 partitions.
+ */
+ if (count <= 0) {
+ CWARN("Can't fit AT information of %s in one page, "
+ "please contact with developer to fix this.\n",
+ svc->srv_name);
+ break;
+ }
+ }
- *eof = 1;
- cur = at_get(&svcpt->scp_at_estimate);
- worst = svcpt->scp_at_estimate.at_worst_ever;
- worstt = svcpt->scp_at_estimate.at_worst_time;
- s2dhms(&ts, cfs_time_current_sec() - worstt);
- if (AT_OFF)
- rc += snprintf(page + rc, count - rc,
- "adaptive timeouts off, using obd_timeout %u\n",
- obd_timeout);
- rc += snprintf(page + rc, count - rc,
- "%10s : cur %3u worst %3u (at %ld, "DHMS_FMT" ago) ",
- "service", cur, worst, worstt,
- DHMS_VARS(&ts));
- rc = lprocfs_at_hist_helper(page, count, rc, &svcpt->scp_at_estimate);
return rc;
}
}
static int ptlrpc_lprocfs_wr_hp_ratio(struct file *file, const char *buffer,
- unsigned long count, void *data)
+ unsigned long count, void *data)
{
- struct ptlrpc_service *svc = data;
- int rc, val;
+ struct ptlrpc_service *svc = data;
+ int rc;
+ int val;
- rc = lprocfs_write_helper(buffer, count, &val);
- if (rc < 0)
- return rc;
- if (val < 0)
- return -ERANGE;
+ rc = lprocfs_write_helper(buffer, count, &val);
+ if (rc < 0)
+ return rc;
+
+ if (val < 0)
+ return -ERANGE;
cfs_spin_lock(&svc->srv_lock);
svc->srv_hpreq_ratio = val;