4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License version 2 for more details. A copy is
14 * included in the COPYING file that accompanied this code.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * Copyright (c) 2011 Intel Corporation
25 * Copyright 2012 Xyratex Technology Limited
28 * lustre/ptlrpc/nrs_fifo.c
30 * Network Request Scheduler (NRS) FIFO policy
32 * Handles RPCs in a FIFO manner, as received from the network. This policy is
33 * a logical wrapper around previous, non-NRS functionality. It is used as the
34 * default and fallback policy for all types of RPCs on all PTLRPC service
35 * partitions, for both regular and high-priority NRS heads. Default here means
36 * the policy is the one enabled at PTLRPC service partition startup time, and
37 * fallback means the policy is used to handle RPCs that are not handled
38 * successfully or are not handled at all by any primary policy that may be
39 * enabled on a given NRS head.
41 * Author: Liang Zhen <liang@whamcloud.com>
42 * Author: Nikitas Angelinas <nikitas_angelinas@xyratex.com>
49 #define DEBUG_SUBSYSTEM S_RPC
51 #include <liblustre.h>
53 #include <obd_support.h>
54 #include <obd_class.h>
55 #include <libcfs/libcfs.h>
56 #include "ptlrpc_internal.h"
61 * The FIFO policy is a logical wrapper around previous, non-NRS functionality.
62 * It schedules RPCs in the same order as they are queued from LNet.
68 * Is called before the policy transitions into
69 * ptlrpc_nrs_pol_state::NRS_POL_STATE_STARTED; allocates and initializes a
70 * policy-specific private data structure.
72 * \param[in] policy The policy to start
74 * \retval -ENOMEM OOM error
77 * \see nrs_policy_register()
78 * \see nrs_policy_ctl()
81 nrs_fifo_start(struct ptlrpc_nrs_policy *policy)
83 struct nrs_fifo_head *head;
85 OBD_CPT_ALLOC_PTR(head, nrs_pol2cptab(policy), nrs_pol2cptid(policy));
89 CFS_INIT_LIST_HEAD(&head->fh_list);
90 policy->pol_private = head;
95 * Is called before the policy transitions into
96 * ptlrpc_nrs_pol_state::NRS_POL_STATE_STOPPED; deallocates the policy-specific
97 * private data structure.
99 * \param[in] policy The policy to stop
101 * \see nrs_policy_stop0()
104 nrs_fifo_stop(struct ptlrpc_nrs_policy *policy)
106 struct nrs_fifo_head *head = policy->pol_private;
108 LASSERT(head != NULL);
109 LASSERT(cfs_list_empty(&head->fh_list));
115 * Is called for obtaining a FIFO policy resource.
117 * \param[in] policy The policy on which the request is being asked for
118 * \param[in] nrq The request for which resources are being taken
119 * \param[in] parent Parent resource, unused in this policy
120 * \param[out] resp Resources references are placed in this array
121 * \param[in] moving_req Signifies limited caller context; unused in this
124 * \retval 1 The FIFO policy only has a one-level resource hierarchy, as since
125 * it implements a simple scheduling algorithm in which request
126 * priority is determined on the request arrival order, it does not
127 * need to maintain a set of resources that would otherwise be used
128 * to calculate a request's priority.
130 * \see nrs_resource_get_safe()
133 nrs_fifo_res_get(struct ptlrpc_nrs_policy *policy,
134 struct ptlrpc_nrs_request *nrq,
135 struct ptlrpc_nrs_resource *parent,
136 struct ptlrpc_nrs_resource **resp, bool moving_req)
139 * Just return the resource embedded inside nrs_fifo_head, and end this
140 * resource hierarchy reference request.
142 *resp = &((struct nrs_fifo_head *)policy->pol_private)->fh_res;
147 * Called when polling the fifo policy for a request.
149 * \param[in] policy The policy being polled
151 * \retval The request to be handled; this is the next request in the FIFO
153 * \see ptlrpc_nrs_req_poll_nolock()
155 static struct ptlrpc_nrs_request *
156 nrs_fifo_req_poll(struct ptlrpc_nrs_policy *policy)
158 struct nrs_fifo_head *head = policy->pol_private;
160 LASSERT(head != NULL);
162 return cfs_list_empty(&head->fh_list) ? NULL :
163 cfs_list_entry(head->fh_list.next, struct ptlrpc_nrs_request,
168 * Adds request \a nrq to \a policy's list of queued requests
170 * \param[in] policy The policy
171 * \param[in] nrq The request to add
173 * \retval 0 success; nrs_request_enqueue() assumes this function will always
177 nrs_fifo_req_add(struct ptlrpc_nrs_policy *policy,
178 struct ptlrpc_nrs_request *nrq)
180 struct nrs_fifo_head *head;
182 head = container_of(nrs_request_resource(nrq), struct nrs_fifo_head,
185 * Only used for debugging
187 nrq->nr_u.fifo.fr_sequence = head->fh_sequence++;
188 cfs_list_add_tail(&nrq->nr_u.fifo.fr_list, &head->fh_list);
194 * Removes request \a nrq from \a policy's list of queued requests.
196 * \param[in] policy The policy
197 * \param[in] nrq The request to remove
200 nrs_fifo_req_del(struct ptlrpc_nrs_policy *policy,
201 struct ptlrpc_nrs_request *nrq)
203 LASSERT(!cfs_list_empty(&nrq->nr_u.fifo.fr_list));
204 cfs_list_del_init(&nrq->nr_u.fifo.fr_list);
208 * Prints a debug statement right before the request \a nrq starts being
211 * \param[in] policy The policy handling the request
212 * \param[in] nrq The request being handled
215 nrs_fifo_req_start(struct ptlrpc_nrs_policy *policy,
216 struct ptlrpc_nrs_request *nrq)
218 struct ptlrpc_request *req = container_of(nrq, struct ptlrpc_request,
221 CDEBUG(D_RPCTRACE, "NRS start %s request from %s, seq: "LPU64"\n",
222 nrs_request_policy(nrq)->pol_name, libcfs_id2str(req->rq_peer),
223 nrq->nr_u.fifo.fr_sequence);
227 * Prints a debug statement right before the request \a nrq stops being
230 * \param[in] policy The policy handling the request
231 * \param[in] nrq The request being handled
233 * \see ptlrpc_server_finish_request()
234 * \see ptlrpc_nrs_req_stop_nolock()
237 nrs_fifo_req_stop(struct ptlrpc_nrs_policy *policy,
238 struct ptlrpc_nrs_request *nrq)
240 struct ptlrpc_request *req = container_of(nrq, struct ptlrpc_request,
243 CDEBUG(D_RPCTRACE, "NRS stop %s request from %s, seq: "LPU64"\n",
244 nrs_request_policy(nrq)->pol_name, libcfs_id2str(req->rq_peer),
245 nrq->nr_u.fifo.fr_sequence);
249 * FIFO policy operations
251 static struct ptlrpc_nrs_pol_ops nrs_fifo_ops = {
252 .op_policy_start = nrs_fifo_start,
253 .op_policy_stop = nrs_fifo_stop,
254 .op_res_get = nrs_fifo_res_get,
255 .op_req_poll = nrs_fifo_req_poll,
256 .op_req_enqueue = nrs_fifo_req_add,
257 .op_req_dequeue = nrs_fifo_req_del,
258 .op_req_start = nrs_fifo_req_start,
259 .op_req_stop = nrs_fifo_req_stop,
263 * FIFO policy descriptor
265 struct ptlrpc_nrs_pol_desc ptlrpc_nrs_fifo_desc = {
267 .pd_ops = &nrs_fifo_ops,
268 .pd_compat = nrs_policy_compat_all,
269 .pd_flags = PTLRPC_NRS_FL_FALLBACK |
270 PTLRPC_NRS_FL_REG_START