- CFS_INIT_LIST_HEAD(&service->srv_free_rs_list);
- cfs_waitq_init(&service->srv_free_rs_waitq);
- atomic_set(&service->srv_n_difficult_replies, 0);
-
- spin_lock_init(&service->srv_at_lock);
- CFS_INIT_LIST_HEAD(&service->srv_req_in_queue);
- CFS_INIT_LIST_HEAD(&service->srv_at_list);
- cfs_timer_init(&service->srv_at_timer, ptlrpc_at_timer, service);
- /* At SOW, service time should be quick; 10s seems generous. If client
- timeout is less than this, we'll be sending an early reply. */
- at_init(&service->srv_at_estimate, 10, 0);
-
- spin_lock (&ptlrpc_all_services_lock);
- list_add (&service->srv_list, &ptlrpc_all_services);
- spin_unlock (&ptlrpc_all_services_lock);
-
- /* Now allocate the request buffers */
- rc = ptlrpc_grow_req_bufs(service);
- /* We shouldn't be under memory pressure at startup, so
- * fail if we can't post all our buffers at this time. */
- if (rc != 0)
- GOTO(failed, NULL);
-
- /* Now allocate pool of reply buffers */
- /* Increase max reply size to next power of two */
- service->srv_max_reply_size = 1;
- while (service->srv_max_reply_size <
- max_reply_size + SPTLRPC_MAX_PAYLOAD)
- service->srv_max_reply_size <<= 1;
+ CFS_INIT_LIST_HEAD(&svcpt->scp_rep_idle);
+ cfs_waitq_init(&svcpt->scp_rep_waitq);
+ cfs_atomic_set(&svcpt->scp_nreps_difficult, 0);
+
+ /* adaptive timeout */
+ cfs_spin_lock_init(&svcpt->scp_at_lock);
+ array = &svcpt->scp_at_array;
+
+ size = at_est2timeout(at_max);
+ array->paa_size = size;
+ array->paa_count = 0;
+ array->paa_deadline = -1;
+
+ /* allocate memory for scp_at_array (ptlrpc_at_array) */
+ OBD_ALLOC(array->paa_reqs_array, sizeof(cfs_list_t) * size);
+ if (array->paa_reqs_array == NULL)
+ return -ENOMEM;
+
+ for (index = 0; index < size; index++)
+ CFS_INIT_LIST_HEAD(&array->paa_reqs_array[index]);
+
+ OBD_ALLOC(array->paa_reqs_count, sizeof(__u32) * size);
+ if (array->paa_reqs_count == NULL)
+ goto failed;
+
+ cfs_timer_init(&svcpt->scp_at_timer, ptlrpc_at_timer, svcpt);
+ /* At SOW, service time should be quick; 10s seems generous. If client
+ * timeout is less than this, we'll be sending an early reply. */
+ at_init(&svcpt->scp_at_estimate, 10, 0);
+
+ /* assign this before call ptlrpc_grow_req_bufs */
+ svcpt->scp_service = svc;
+ /* Now allocate the request buffers, but don't post them now */
+ rc = ptlrpc_grow_req_bufs(svcpt);
+ /* We shouldn't be under memory pressure at startup, so
+ * fail if we can't allocate all our buffers at this time. */
+ if (rc != 0)
+ goto failed;
+
+ return 0;
+
+ failed:
+ if (array->paa_reqs_count != NULL) {
+ OBD_FREE(array->paa_reqs_count, sizeof(__u32) * size);
+ array->paa_reqs_count = NULL;
+ }
+
+ if (array->paa_reqs_array != NULL) {
+ OBD_FREE(array->paa_reqs_array,
+ sizeof(cfs_list_t) * array->paa_size);
+ array->paa_reqs_array = NULL;
+ }
+
+ return -ENOMEM;
+}
+
+/**
+ * Initialize service on a given portal.
+ * This includes starting serving threads , allocating and posting rqbds and
+ * so on.
+ */
+struct ptlrpc_service *
+ptlrpc_register_service(struct ptlrpc_service_conf *conf,
+ cfs_proc_dir_entry_t *proc_entry)
+{
+ struct ptlrpc_service *service;
+ int rc;
+ ENTRY;
+
+ LASSERT(conf->psc_buf.bc_nbufs > 0);
+ LASSERT(conf->psc_buf.bc_buf_size >=
+ conf->psc_buf.bc_req_max_size + SPTLRPC_MAX_PAYLOAD);
+ LASSERT(conf->psc_thr.tc_ctx_tags != 0);
+
+ OBD_ALLOC_PTR(service);
+ if (service == NULL)
+ RETURN(ERR_PTR(-ENOMEM));
+
+ /* public members */
+ cfs_spin_lock_init(&service->srv_lock);
+ service->srv_name = conf->psc_name;
+ service->srv_watchdog_factor = conf->psc_watchdog_factor;
+ CFS_INIT_LIST_HEAD(&service->srv_list); /* for safty of cleanup */
+
+ /* buffer configuration */
+ service->srv_nbuf_per_group = test_req_buffer_pressure ?
+ 1 : conf->psc_buf.bc_nbufs;
+ service->srv_max_req_size = conf->psc_buf.bc_req_max_size +
+ SPTLRPC_MAX_PAYLOAD;
+ service->srv_buf_size = conf->psc_buf.bc_buf_size;
+ service->srv_rep_portal = conf->psc_buf.bc_rep_portal;
+ service->srv_req_portal = conf->psc_buf.bc_req_portal;
+
+ /* Increase max reply size to next power of two */
+ service->srv_max_reply_size = 1;
+ while (service->srv_max_reply_size <
+ conf->psc_buf.bc_rep_max_size + SPTLRPC_MAX_PAYLOAD)
+ service->srv_max_reply_size <<= 1;
+
+ ptlrpc_server_nthreads_check(conf, &service->srv_threads_min,
+ &service->srv_threads_max);
+
+ service->srv_thread_name = conf->psc_thr.tc_thr_name;
+ service->srv_ctx_tags = conf->psc_thr.tc_ctx_tags;
+ service->srv_cpu_affinity = !!conf->psc_thr.tc_cpu_affinity;
+ service->srv_hpreq_ratio = PTLRPC_SVC_HP_RATIO;
+ service->srv_ops = conf->psc_ops;
+
+ OBD_ALLOC_PTR(service->srv_part);
+ if (service->srv_part == NULL)
+ GOTO(failed, rc = -ENOMEM);
+
+ rc = ptlrpc_service_part_init(service, service->srv_part);
+ if (rc != 0)
+ GOTO(failed, rc);
+
+ rc = LNetSetLazyPortal(service->srv_req_portal);
+ LASSERT(rc == 0);
+
+ cfs_spin_lock (&ptlrpc_all_services_lock);
+ cfs_list_add (&service->srv_list, &ptlrpc_all_services);
+ cfs_spin_unlock (&ptlrpc_all_services_lock);