Whamcloud - gitweb
LU-9679 ptlrpc: use OBD_ALLOC_PTR_ARRAY() and FREE
[fs/lustre-release.git] / lustre / ptlrpc / service.c
index eb6057e..f5d11fd 100644 (file)
@@ -65,7 +65,7 @@ static void ptlrpc_server_hpreq_fini(struct ptlrpc_request *req);
 static void ptlrpc_at_remove_timed(struct ptlrpc_request *req);
 
 /** Holds a list of all PTLRPC services */
-struct list_head ptlrpc_all_services;
+LIST_HEAD(ptlrpc_all_services);
 /** Used to protect the \e ptlrpc_all_services list */
 struct mutex ptlrpc_all_services_mutex;
 
@@ -229,7 +229,7 @@ struct ptlrpc_hr_partition {
 #define HRT_STOPPING 1
 
 struct ptlrpc_hr_service {
-       /* CPU partition table, it's just cfs_cpt_table for now */
+       /* CPU partition table, it's just cfs_cpt_tab for now */
        struct cfs_cpt_table            *hr_cpt_table;
        /** controller sleep waitq */
        wait_queue_head_t               hr_waitq;
@@ -684,13 +684,12 @@ static int ptlrpc_service_part_init(struct ptlrpc_service *svc,
 
  failed:
        if (array->paa_reqs_count != NULL) {
-               OBD_FREE(array->paa_reqs_count, sizeof(__u32) * size);
+               OBD_FREE_PTR_ARRAY(array->paa_reqs_count, size);
                array->paa_reqs_count = NULL;
        }
 
        if (array->paa_reqs_array != NULL) {
-               OBD_FREE(array->paa_reqs_array,
-                        sizeof(struct list_head) * array->paa_size);
+               OBD_FREE_PTR_ARRAY(array->paa_reqs_array, array->paa_size);
                array->paa_reqs_array = NULL;
        }
 
@@ -725,7 +724,7 @@ struct ptlrpc_service *ptlrpc_register_service(struct ptlrpc_service_conf *conf,
 
        cptable = cconf->cc_cptable;
        if (cptable == NULL)
-               cptable = cfs_cpt_table;
+               cptable = cfs_cpt_tab;
 
        if (conf->psc_thr.tc_cpu_bind > 1) {
                CERROR("%s: Invalid cpu bind value %d, only 1 or 0 allowed\n",
@@ -755,7 +754,7 @@ struct ptlrpc_service *ptlrpc_register_service(struct ptlrpc_service_conf *conf,
                                CERROR("%s: failed to parse CPT array %s: %d\n",
                                       conf->psc_name, cconf->cc_pattern, rc);
                                if (cpts != NULL)
-                                       OBD_FREE(cpts, sizeof(*cpts) * ncpts);
+                                       OBD_FREE_PTR_ARRAY(cpts, ncpts);
                                RETURN(ERR_PTR(rc < 0 ? rc : -EINVAL));
                        }
                        ncpts = rc;
@@ -765,7 +764,7 @@ struct ptlrpc_service *ptlrpc_register_service(struct ptlrpc_service_conf *conf,
        OBD_ALLOC(service, offsetof(struct ptlrpc_service, srv_parts[ncpts]));
        if (service == NULL) {
                if (cpts != NULL)
-                       OBD_FREE(cpts, sizeof(*cpts) * ncpts);
+                       OBD_FREE_PTR_ARRAY(cpts, ncpts);
                RETURN(ERR_PTR(-ENOMEM));
        }
 
@@ -1072,8 +1071,6 @@ void ptlrpc_request_change_export(struct ptlrpc_request *req,
        /* request takes one export refcount */
        req->rq_export = class_export_get(export);
        class_export_rpc_inc(export);
-
-       return;
 }
 
 /**
@@ -1353,7 +1350,7 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
        struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt;
        struct ptlrpc_request *reqcopy;
        struct lustre_msg *reqmsg;
-       time64_t olddl = req->rq_deadline - ktime_get_real_seconds();
+       timeout_t olddl = req->rq_deadline - ktime_get_real_seconds();
        time64_t newdl;
        int rc;
 
@@ -1369,9 +1366,9 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
         * difference between clients' and servers' expectations
         */
        DEBUG_REQ(D_ADAPTTO, req,
-                 "%ssending early reply (deadline %+llds, margin %+llds) for %d+%d",
+                 "%ssending early reply (deadline %+ds, margin %+ds) for %d+%d",
                  AT_OFF ? "AT off - not " : "",
-                 (s64)olddl, (s64)(olddl - at_get(&svcpt->scp_at_estimate)),
+                 olddl, olddl - at_get(&svcpt->scp_at_estimate),
                  at_get(&svcpt->scp_at_estimate), at_extra);
 
        if (AT_OFF)
@@ -1380,8 +1377,8 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
        if (olddl < 0) {
                /* below message is checked in replay-ost-single.sh test_9 */
                DEBUG_REQ(D_WARNING, req,
-                         "Already past deadline (%+llds), not sending early reply. Consider increasing at_early_margin (%d)?",
-                         (s64)olddl, at_early_margin);
+                         "Already past deadline (%+ds), not sending early reply. Consider increasing at_early_margin (%d)?",
+                         olddl, at_early_margin);
 
                /* Return an error so we're not re-added to the timed list. */
                RETURN(-ETIMEDOUT);
@@ -1438,8 +1435,8 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
         */
        if (req->rq_deadline >= newdl) {
                DEBUG_REQ(D_WARNING, req,
-                         "Could not add any time (%lld/%lld), not sending early reply",
-                         (s64)olddl, (s64)(newdl - ktime_get_real_seconds()));
+                         "Could not add any time (%d/%lld), not sending early reply",
+                         olddl, newdl - ktime_get_real_seconds());
                RETURN(-ETIMEDOUT);
        }
 
@@ -1528,11 +1525,11 @@ static int ptlrpc_at_check_timed(struct ptlrpc_service_part *svcpt)
 {
        struct ptlrpc_at_array *array = &svcpt->scp_at_array;
        struct ptlrpc_request *rq, *n;
-       struct list_head work_list;
+       LIST_HEAD(work_list);
        __u32 index, count;
        time64_t deadline;
        time64_t now = ktime_get_real_seconds();
-       s64 delay;
+       s64 delay_ms;
        int first, counter = 0;
 
        ENTRY;
@@ -1541,7 +1538,7 @@ static int ptlrpc_at_check_timed(struct ptlrpc_service_part *svcpt)
                spin_unlock(&svcpt->scp_at_lock);
                RETURN(0);
        }
-       delay = ktime_ms_delta(ktime_get(), svcpt->scp_at_checktime);
+       delay_ms = ktime_ms_delta(ktime_get(), svcpt->scp_at_checktime);
        svcpt->scp_at_check = 0;
 
        if (array->paa_count == 0) {
@@ -1562,7 +1559,6 @@ static int ptlrpc_at_check_timed(struct ptlrpc_service_part *svcpt)
         * We're close to a timeout, and we don't know how much longer the
         * server will take. Send early replies to everyone expiring soon.
         */
-       INIT_LIST_HEAD(&work_list);
        deadline = -1;
        div_u64_rem(array->paa_deadline, array->paa_size, &index);
        count = array->paa_count;
@@ -1613,10 +1609,10 @@ static int ptlrpc_at_check_timed(struct ptlrpc_service_part *svcpt)
                 */
                LCONSOLE_WARN("%s: This server is not able to keep up with request traffic (cpu-bound).\n",
                              svcpt->scp_service->srv_name);
-               CWARN("earlyQ=%d reqQ=%d recA=%d, svcEst=%d, delay=%lld\n",
+               CWARN("earlyQ=%d reqQ=%d recA=%d, svcEst=%d, delay=%lldms\n",
                      counter, svcpt->scp_nreqs_incoming,
                      svcpt->scp_nreqs_active,
-                     at_get(&svcpt->scp_at_estimate), delay);
+                     at_get(&svcpt->scp_at_estimate), delay_ms);
        }
 
        /*
@@ -2164,8 +2160,8 @@ static int ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt,
        /* req_in handling should/must be fast */
        if (ktime_get_real_seconds() - req->rq_arrival_time.tv_sec > 5)
                DEBUG_REQ(D_WARNING, req, "Slow req_in handling %llds",
-                         (s64)(ktime_get_real_seconds() -
-                               req->rq_arrival_time.tv_sec));
+                         ktime_get_real_seconds() -
+                         req->rq_arrival_time.tv_sec);
 
        /* Set rpc server deadline and add it to the timed list */
        deadline = (lustre_msghdr_get_flags(req->rq_reqmsg) &
@@ -2292,11 +2288,11 @@ static int ptlrpc_server_handle_request(struct ptlrpc_service_part *svcpt,
 
        CDEBUG(D_RPCTRACE,
               "Handling RPC req@%p pname:cluuid+ref:pid:xid:nid:opc:job %s:%s+%d:%d:x%llu:%s:%d:%s\n",
-              request, current_comm(),
+              request, current->comm,
               (request->rq_export ?
                (char *)request->rq_export->exp_client_uuid.uuid : "0"),
               (request->rq_export ?
-               atomic_read(&request->rq_export->exp_refcount) : -99),
+               refcount_read(&request->rq_export->exp_handle.h_ref) : -99),
               lustre_msg_get_status(request->rq_reqmsg), request->rq_xid,
               libcfs_id2str(request->rq_peer),
               lustre_msg_get_opc(request->rq_reqmsg),
@@ -2332,11 +2328,11 @@ put_conn:
        arrived_usecs = ktime_us_delta(work_end, arrived);
        CDEBUG(D_RPCTRACE,
               "Handled RPC req@%p pname:cluuid+ref:pid:xid:nid:opc:job %s:%s+%d:%d:x%llu:%s:%d:%s Request processed in %lldus (%lldus total) trans %llu rc %d/%d\n",
-              request, current_comm(),
+              request, current->comm,
               (request->rq_export ?
               (char *)request->rq_export->exp_client_uuid.uuid : "0"),
               (request->rq_export ?
-              atomic_read(&request->rq_export->exp_refcount) : -99),
+               refcount_read(&request->rq_export->exp_handle.h_ref) : -99),
               lustre_msg_get_status(request->rq_reqmsg),
               request->rq_xid,
               libcfs_id2str(request->rq_peer),
@@ -2556,14 +2552,6 @@ static void ptlrpc_check_rqbd_pool(struct ptlrpc_service_part *svcpt)
        }
 }
 
-static int ptlrpc_retry_rqbds(void *arg)
-{
-       struct ptlrpc_service_part *svcpt = (struct ptlrpc_service_part *)arg;
-
-       svcpt->scp_rqbd_timeout = 0;
-       return -ETIMEDOUT;
-}
-
 static inline int ptlrpc_threads_enough(struct ptlrpc_service_part *svcpt)
 {
        return svcpt->scp_nreqs_active <
@@ -2672,10 +2660,10 @@ static void ptlrpc_watchdog_fire(struct work_struct *w)
        }
 }
 
-static void ptlrpc_watchdog_init(struct delayed_work *work, time_t time)
+static void ptlrpc_watchdog_init(struct delayed_work *work, timeout_t timeout)
 {
        INIT_DELAYED_WORK(work, ptlrpc_watchdog_fire);
-       schedule_delayed_work(work, cfs_time_seconds(time));
+       schedule_delayed_work(work, cfs_time_seconds(timeout));
 }
 
 static void ptlrpc_watchdog_disable(struct delayed_work *work)
@@ -2683,13 +2671,13 @@ static void ptlrpc_watchdog_disable(struct delayed_work *work)
        cancel_delayed_work_sync(work);
 }
 
-static void ptlrpc_watchdog_touch(struct delayed_work *work, time_t time)
+static void ptlrpc_watchdog_touch(struct delayed_work *work, timeout_t timeout)
 {
        struct ptlrpc_thread *thread = container_of(&work->work,
                                                    struct ptlrpc_thread,
                                                    t_watchdog.work);
        thread->t_touched = ktime_get();
-       mod_delayed_work(system_wq, work, cfs_time_seconds(time));
+       mod_delayed_work(system_wq, work, cfs_time_seconds(timeout));
 }
 
 /**
@@ -2707,20 +2695,28 @@ static __attribute__((__noinline__)) int
 ptlrpc_wait_event(struct ptlrpc_service_part *svcpt,
                  struct ptlrpc_thread *thread)
 {
-       /* Don't exit while there are replies to be handled */
-       struct l_wait_info lwi = LWI_TIMEOUT(svcpt->scp_rqbd_timeout,
-                                            ptlrpc_retry_rqbds, svcpt);
-
        ptlrpc_watchdog_disable(&thread->t_watchdog);
 
        cond_resched();
 
-       l_wait_event_exclusive_head(svcpt->scp_waitq,
-                               ptlrpc_thread_stopping(thread) ||
-                               ptlrpc_server_request_incoming(svcpt) ||
-                               ptlrpc_server_request_pending(svcpt, false) ||
-                               ptlrpc_rqbd_pending(svcpt) ||
-                               ptlrpc_at_check(svcpt), &lwi);
+       if (svcpt->scp_rqbd_timeout == 0)
+               /* Don't exit while there are replies to be handled */
+               wait_event_idle_exclusive_lifo(
+                       svcpt->scp_waitq,
+                       ptlrpc_thread_stopping(thread) ||
+                       ptlrpc_server_request_incoming(svcpt) ||
+                       ptlrpc_server_request_pending(svcpt, false) ||
+                       ptlrpc_rqbd_pending(svcpt) ||
+                       ptlrpc_at_check(svcpt));
+       else if (wait_event_idle_exclusive_lifo_timeout(
+                        svcpt->scp_waitq,
+                        ptlrpc_thread_stopping(thread) ||
+                        ptlrpc_server_request_incoming(svcpt) ||
+                        ptlrpc_server_request_pending(svcpt, false) ||
+                        ptlrpc_rqbd_pending(svcpt) ||
+                        ptlrpc_at_check(svcpt),
+                        svcpt->scp_rqbd_timeout) == 0)
+               svcpt->scp_rqbd_timeout = 0;
 
        if (ptlrpc_thread_stopping(thread))
                return -EINTR;
@@ -2749,7 +2745,7 @@ static int ptlrpc_main(void *arg)
        ENTRY;
 
        thread->t_task = current;
-       thread->t_pid = current_pid();
+       thread->t_pid = current->pid;
        unshare_fs_struct();
 
        if (svc->srv_cpt_bind) {
@@ -2851,6 +2847,9 @@ static int ptlrpc_main(void *arg)
 
                /* reset le_ses to initial state */
                env->le_ses = NULL;
+               /* Refill the context before execution to make sure
+                * all thread keys are allocated */
+               lu_env_refill(env);
                /* Process all incoming reqs before handling any */
                if (ptlrpc_server_request_incoming(svcpt)) {
                        lu_context_enter(&env->le_ctx);
@@ -2947,7 +2946,7 @@ static int ptlrpc_hr_main(void *arg)
 {
        struct ptlrpc_hr_thread *hrt = (struct ptlrpc_hr_thread *)arg;
        struct ptlrpc_hr_partition *hrp = hrt->hrt_partition;
-       struct list_head replies;
+       LIST_HEAD(replies);
        struct lu_env *env;
        int rc;
 
@@ -2955,7 +2954,6 @@ static int ptlrpc_hr_main(void *arg)
        if (env == NULL)
                RETURN(-ENOMEM);
 
-       INIT_LIST_HEAD(&replies);
        unshare_fs_struct();
 
        rc = cfs_cpt_bind(ptlrpc_hr.hr_cpt_table, hrp->hrp_cpt);
@@ -2981,7 +2979,7 @@ static int ptlrpc_hr_main(void *arg)
        wake_up(&ptlrpc_hr.hr_waitq);
 
        while (!ptlrpc_hr.hr_stopping) {
-               l_wait_condition(hrt->hrt_waitq, hrt_dont_sleep(hrt, &replies));
+               wait_event_idle(hrt->hrt_waitq, hrt_dont_sleep(hrt, &replies));
 
                while (!list_empty(&replies)) {
                        struct ptlrpc_reply_state *rs;
@@ -3076,14 +3074,13 @@ static int ptlrpc_start_hr_threads(void)
 static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt)
 {
        struct ptlrpc_thread *thread;
-       struct list_head zombie;
+       LIST_HEAD(zombie);
 
        ENTRY;
 
        CDEBUG(D_INFO, "Stopping threads for service %s\n",
               svcpt->scp_service->srv_name);
 
-       INIT_LIST_HEAD(&zombie);
        spin_lock(&svcpt->scp_lock);
        /* let the thread know that we would like it to stop asap */
        list_for_each_entry(thread, &svcpt->scp_threads, t_link)
@@ -3289,7 +3286,7 @@ int ptlrpc_hr_init(void)
        ENTRY;
 
        memset(&ptlrpc_hr, 0, sizeof(ptlrpc_hr));
-       ptlrpc_hr.hr_cpt_table = cfs_cpt_table;
+       ptlrpc_hr.hr_cpt_table = cfs_cpt_tab;
 
        ptlrpc_hr.hr_partitions = cfs_percpt_alloc(ptlrpc_hr.hr_cpt_table,
                                                   sizeof(*hrp));
@@ -3350,10 +3347,8 @@ void ptlrpc_hr_fini(void)
        ptlrpc_stop_hr_threads();
 
        cfs_percpt_for_each(hrp, cpt, ptlrpc_hr.hr_partitions) {
-               if (hrp->hrp_thrs != NULL) {
-                       OBD_FREE(hrp->hrp_thrs,
-                                hrp->hrp_nthrs * sizeof(hrp->hrp_thrs[0]));
-               }
+               if (hrp->hrp_thrs)
+                       OBD_FREE_PTR_ARRAY(hrp->hrp_thrs, hrp->hrp_nthrs);
        }
 
        cfs_percpt_free(ptlrpc_hr.hr_partitions);
@@ -3367,13 +3362,10 @@ void ptlrpc_hr_fini(void)
 static void ptlrpc_wait_replies(struct ptlrpc_service_part *svcpt)
 {
        while (1) {
-               int rc;
-               struct l_wait_info lwi = LWI_TIMEOUT(cfs_time_seconds(10),
-                                                    NULL, NULL);
-
-               rc = l_wait_event(svcpt->scp_waitq,
-                    atomic_read(&svcpt->scp_nreps_difficult) == 0, &lwi);
-               if (rc == 0)
+               if (wait_event_idle_timeout(
+                       svcpt->scp_waitq,
+                       atomic_read(&svcpt->scp_nreps_difficult) == 0,
+                       cfs_time_seconds(10)) > 0)
                        break;
                CWARN("Unexpectedly long timeout %s %p\n",
                      svcpt->scp_service->srv_name, svcpt->scp_service);
@@ -3398,7 +3390,6 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc)
 {
        struct ptlrpc_service_part *svcpt;
        struct ptlrpc_request_buffer_desc *rqbd;
-       struct l_wait_info lwi;
        int rc;
        int i;
 
@@ -3436,18 +3427,21 @@ ptlrpc_service_unlink_rqbd(struct ptlrpc_service *svc)
                 */
                spin_lock(&svcpt->scp_lock);
                while (svcpt->scp_nrqbds_posted != 0) {
+                       int seconds = LONG_UNLINK;
+
                        spin_unlock(&svcpt->scp_lock);
                        /*
                         * Network access will complete in finite time but
                         * the HUGE timeout lets us CWARN for visibility
                         * of sluggish NALs
                         */
-                       lwi = LWI_TIMEOUT_INTERVAL(
-                                       cfs_time_seconds(LONG_UNLINK),
-                                       cfs_time_seconds(1), NULL, NULL);
-                       rc = l_wait_event(svcpt->scp_waitq,
-                                         svcpt->scp_nrqbds_posted == 0, &lwi);
-                       if (rc == -ETIMEDOUT) {
+                       while (seconds > 0 &&
+                              wait_event_idle_timeout(
+                                      svcpt->scp_waitq,
+                                      svcpt->scp_nrqbds_posted == 0,
+                                      cfs_time_seconds(1)) == 0)
+                               seconds -= 1;
+                       if (seconds == 0) {
                                CWARN("Service %s waiting for request buffers\n",
                                      svcpt->scp_service->srv_name);
                        }
@@ -3547,14 +3541,14 @@ ptlrpc_service_free(struct ptlrpc_service *svc)
                array = &svcpt->scp_at_array;
 
                if (array->paa_reqs_array != NULL) {
-                       OBD_FREE(array->paa_reqs_array,
-                                sizeof(struct list_head) * array->paa_size);
+                       OBD_FREE_PTR_ARRAY(array->paa_reqs_array,
+                                          array->paa_size);
                        array->paa_reqs_array = NULL;
                }
 
                if (array->paa_reqs_count != NULL) {
-                       OBD_FREE(array->paa_reqs_count,
-                                sizeof(__u32) * array->paa_size);
+                       OBD_FREE_PTR_ARRAY(array->paa_reqs_count,
+                                          array->paa_size);
                        array->paa_reqs_count = NULL;
                }
        }