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
50 #include "../include/obd_support.h"
51 #include "../include/obd_class.h"
52 #include "../../include/linux/libcfs/libcfs.h"
53 #include "ptlrpc_internal.h"
58 * The FIFO policy is a logical wrapper around previous, non-NRS functionality.
59 * It schedules RPCs in the same order as they are queued from LNet.
64 #define NRS_POL_NAME_FIFO "fifo"
67 * Is called before the policy transitions into
68 * ptlrpc_nrs_pol_state::NRS_POL_STATE_STARTED; allocates and initializes a
69 * policy-specific private data structure.
71 * \param[in] policy The policy to start
73 * \retval -ENOMEM OOM error
76 * \see nrs_policy_register()
77 * \see nrs_policy_ctl()
79 static int nrs_fifo_start(struct ptlrpc_nrs_policy
*policy
)
81 struct nrs_fifo_head
*head
;
83 head
= kzalloc_node(sizeof(*head
), GFP_NOFS
,
84 cfs_cpt_spread_node(nrs_pol2cptab(policy
),
85 nrs_pol2cptid(policy
)));
89 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()
103 static void nrs_fifo_stop(struct ptlrpc_nrs_policy
*policy
)
105 struct nrs_fifo_head
*head
= policy
->pol_private
;
107 LASSERT(head
!= NULL
);
108 LASSERT(list_empty(&head
->fh_list
));
114 * Is called for obtaining a FIFO policy resource.
116 * \param[in] policy The policy on which the request is being asked for
117 * \param[in] nrq The request for which resources are being taken
118 * \param[in] parent Parent resource, unused in this policy
119 * \param[out] resp Resources references are placed in this array
120 * \param[in] moving_req Signifies limited caller context; unused in this
123 * \retval 1 The FIFO policy only has a one-level resource hierarchy, as since
124 * it implements a simple scheduling algorithm in which request
125 * priority is determined on the request arrival order, it does not
126 * need to maintain a set of resources that would otherwise be used
127 * to calculate a request's priority.
129 * \see nrs_resource_get_safe()
131 static int nrs_fifo_res_get(struct ptlrpc_nrs_policy
*policy
,
132 struct ptlrpc_nrs_request
*nrq
,
133 const struct ptlrpc_nrs_resource
*parent
,
134 struct ptlrpc_nrs_resource
**resp
, bool moving_req
)
137 * Just return the resource embedded inside nrs_fifo_head, and end this
138 * resource hierarchy reference request.
140 *resp
= &((struct nrs_fifo_head
*)policy
->pol_private
)->fh_res
;
145 * Called when getting a request from the FIFO policy for handling, or just
146 * peeking; removes the request from the policy when it is to be handled.
148 * \param[in] policy The policy
149 * \param[in] peek When set, signifies that we just want to examine the
150 * request, and not handle it, so the request is not removed
152 * \param[in] force Force the policy to return a request; unused in this
155 * \retval The request to be handled; this is the next request in the FIFO
158 * \see ptlrpc_nrs_req_get_nolock()
159 * \see nrs_request_get()
162 struct ptlrpc_nrs_request
*nrs_fifo_req_get(struct ptlrpc_nrs_policy
*policy
,
163 bool peek
, bool force
)
165 struct nrs_fifo_head
*head
= policy
->pol_private
;
166 struct ptlrpc_nrs_request
*nrq
;
168 nrq
= unlikely(list_empty(&head
->fh_list
)) ? NULL
:
169 list_entry(head
->fh_list
.next
, struct ptlrpc_nrs_request
,
172 if (likely(!peek
&& nrq
!= NULL
)) {
173 struct ptlrpc_request
*req
= container_of(nrq
,
174 struct ptlrpc_request
,
177 list_del_init(&nrq
->nr_u
.fifo
.fr_list
);
179 CDEBUG(D_RPCTRACE
, "NRS start %s request from %s, seq: %llu\n",
180 policy
->pol_desc
->pd_name
, libcfs_id2str(req
->rq_peer
),
181 nrq
->nr_u
.fifo
.fr_sequence
);
188 * Adds request \a nrq to \a policy's list of queued requests
190 * \param[in] policy The policy
191 * \param[in] nrq The request to add
193 * \retval 0 success; nrs_request_enqueue() assumes this function will always
196 static int nrs_fifo_req_add(struct ptlrpc_nrs_policy
*policy
,
197 struct ptlrpc_nrs_request
*nrq
)
199 struct nrs_fifo_head
*head
;
201 head
= container_of(nrs_request_resource(nrq
), struct nrs_fifo_head
,
204 * Only used for debugging
206 nrq
->nr_u
.fifo
.fr_sequence
= head
->fh_sequence
++;
207 list_add_tail(&nrq
->nr_u
.fifo
.fr_list
, &head
->fh_list
);
213 * Removes request \a nrq from \a policy's list of queued requests.
215 * \param[in] policy The policy
216 * \param[in] nrq The request to remove
218 static void nrs_fifo_req_del(struct ptlrpc_nrs_policy
*policy
,
219 struct ptlrpc_nrs_request
*nrq
)
221 LASSERT(!list_empty(&nrq
->nr_u
.fifo
.fr_list
));
222 list_del_init(&nrq
->nr_u
.fifo
.fr_list
);
226 * Prints a debug statement right before the request \a nrq stops being
229 * \param[in] policy The policy handling the request
230 * \param[in] nrq The request being handled
232 * \see ptlrpc_server_finish_request()
233 * \see ptlrpc_nrs_req_stop_nolock()
235 static void nrs_fifo_req_stop(struct ptlrpc_nrs_policy
*policy
,
236 struct ptlrpc_nrs_request
*nrq
)
238 struct ptlrpc_request
*req
= container_of(nrq
, struct ptlrpc_request
,
241 CDEBUG(D_RPCTRACE
, "NRS stop %s request from %s, seq: %llu\n",
242 policy
->pol_desc
->pd_name
, libcfs_id2str(req
->rq_peer
),
243 nrq
->nr_u
.fifo
.fr_sequence
);
247 * FIFO policy operations
249 static const struct ptlrpc_nrs_pol_ops nrs_fifo_ops
= {
250 .op_policy_start
= nrs_fifo_start
,
251 .op_policy_stop
= nrs_fifo_stop
,
252 .op_res_get
= nrs_fifo_res_get
,
253 .op_req_get
= nrs_fifo_req_get
,
254 .op_req_enqueue
= nrs_fifo_req_add
,
255 .op_req_dequeue
= nrs_fifo_req_del
,
256 .op_req_stop
= nrs_fifo_req_stop
,
260 * FIFO policy configuration
262 struct ptlrpc_nrs_pol_conf nrs_conf_fifo
= {
263 .nc_name
= NRS_POL_NAME_FIFO
,
264 .nc_ops
= &nrs_fifo_ops
,
265 .nc_compat
= nrs_policy_compat_all
,
266 .nc_flags
= PTLRPC_NRS_FL_FALLBACK
|
267 PTLRPC_NRS_FL_REG_START