- /*
- * NB: we will add some common code here for estimating, for example:
- * add a new member ptlrpc_service_thr_conf::tc_factor, and estimate
- * threads number based on:
- * (online_cpus * conf::tc_factor) + conf::tc_nthrs_base.
- *
- * So we can remove code block like estimation in ost_setup, also,
- * we might estimate MDS threads number as well instead of using
- * absolute number, and have more threads on fat servers to improve
- * availability of service.
- *
- * Also, we will need to validate threads number at here for
- * CPT affinity service (CPU ParTion) in the future.
- * A service can have percpt thread-pool instead of a global thread
- * pool for each service, which means user might not always get the
- * threads number they want even they set it in conf::tc_nthrs_user,
- * because we need to adjust threads number for each CPT, instead of
- * just use (conf::tc_nthrs_user / NCPTS), to make sure each pool
- * will be healthy.
- */
- *max_p = tc->tc_nthrs_max;
- *min_p = nthrs_min;
-#else /* __KERNEL__ */
- *max_p = *min_p = 1; /* whatever */
+ nthrs = tc->tc_nthrs_base;
+ if (svc->srv_ncpts == 1) {
+ int i;
+
+ /* NB: Increase the base number if it's single partition
+ * and total number of cores/HTs is larger or equal to 4.
+ * result will always < 2 * nthrs_base */
+ weight = cfs_cpt_weight(svc->srv_cptable, CFS_CPT_ANY);
+ for (i = 1; (weight >> (i + 1)) != 0 && /* >= 4 cores/HTs */
+ (tc->tc_nthrs_base >> i) != 0; i++)
+ nthrs += tc->tc_nthrs_base >> i;
+ }
+
+ if (tc->tc_thr_factor != 0) {
+ int factor = tc->tc_thr_factor;
+ const int fade = 4;
+
+ /*
+ * User wants to increase number of threads with for
+ * each CPU core/HT, most likely the factor is larger then
+ * one thread/core because service threads are supposed to
+ * be blocked by lock or wait for IO.
+ */
+ /*
+ * Amdahl's law says that adding processors wouldn't give
+ * a linear increasing of parallelism, so it's nonsense to
+ * have too many threads no matter how many cores/HTs
+ * there are.
+ */
+ if (cfs_cpu_ht_nsiblings(0) > 1) { /* weight is # of HTs */
+ /* depress thread factor for hyper-thread */
+ factor = factor - (factor >> 1) + (factor >> 3);
+ }
+
+ weight = cfs_cpt_weight(svc->srv_cptable, 0);
+ LASSERT(weight > 0);
+
+ for (; factor > 0 && weight > 0; factor--, weight -= fade)
+ nthrs += min(weight, fade) * factor;
+ }
+
+ if (nthrs * svc->srv_ncpts > tc->tc_nthrs_max) {
+ nthrs = max(tc->tc_nthrs_base,
+ tc->tc_nthrs_max / svc->srv_ncpts);
+ }
+ out:
+ nthrs = max(nthrs, tc->tc_nthrs_init);
+ svc->srv_nthrs_cpt_limit = nthrs;
+ svc->srv_nthrs_cpt_init = init;
+
+ if (nthrs * svc->srv_ncpts > tc->tc_nthrs_max) {
+ LCONSOLE_WARN("%s: This service may have more threads (%d) "
+ "than the given soft limit (%d)\n",
+ svc->srv_name, nthrs * svc->srv_ncpts,
+ tc->tc_nthrs_max);
+ }