/* * GPL HEADER START * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 only, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License version 2 for more details. * * You should have received a copy of the GNU General Public License * along with this program; If not, see * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ /* * Copyright (C) 2013 DataDirect Networks, Inc. * * Copyright (c) 2014, Intel Corporation. */ /* * * Network Request Scheduler (NRS) Token Bucket Filter(TBF) policy * */ #ifndef _LUSTRE_NRS_TBF_H #define _LUSTRE_NRS_TBF_H /* \name tbf * * TBF policy * * @{ */ struct nrs_tbf_head; struct nrs_tbf_cmd; #define NRS_TBF_MATCH_FULL 0x0000001 #define NRS_TBF_MATCH_WILDCARD 0x0000002 struct nrs_tbf_jobid { char *tj_id; __u32 tj_match_flag; struct list_head tj_linkage; }; #define MAX_U32_STR_LEN 10 #define NRS_TBF_KEY_LEN (LNET_NIDSTR_SIZE + LUSTRE_JOBID_SIZE + \ MAX_U32_STR_LEN + MAX_U32_STR_LEN + 3 + 2) enum nrs_tbf_flag { NRS_TBF_FLAG_INVALID = 0x0000000, NRS_TBF_FLAG_JOBID = 0x0000001, NRS_TBF_FLAG_NID = 0x0000002, NRS_TBF_FLAG_OPCODE = 0x0000004, NRS_TBF_FLAG_GENERIC = 0x0000008, NRS_TBF_FLAG_UID = 0x0000010, NRS_TBF_FLAG_GID = 0x0000020, }; struct tbf_id { enum nrs_tbf_flag ti_type; u32 ti_uid; u32 ti_gid; }; struct nrs_tbf_id { struct tbf_id nti_id; struct list_head nti_linkage; }; struct nrs_tbf_client { /** Resource object for policy instance. */ struct ptlrpc_nrs_resource tc_res; /** Node in the hash table. */ struct hlist_node tc_hnode; /** NID of the client. */ struct lnet_nid tc_nid; /** Jobid of the client. */ char tc_jobid[LUSTRE_JOBID_SIZE]; /** opcode of the client. */ __u32 tc_opcode; /** gid or uid of the client. */ struct tbf_id tc_id; /** Hash key of the client. */ char tc_key[NRS_TBF_KEY_LEN]; /** Reference number of the client. */ refcount_t tc_ref; /** Lock to protect rule and linkage. */ spinlock_t tc_rule_lock; /** Linkage to rule. */ struct list_head tc_linkage; /** Pointer to rule. */ struct nrs_tbf_rule *tc_rule; /** Generation of the rule matched. */ __u64 tc_rule_generation; /** Limit of RPC rate. */ __u64 tc_rpc_rate; /** Time to wait for next token. */ __u64 tc_nsecs; /** RPC token number. */ __u64 tc_ntoken; /** Token bucket depth. */ __u64 tc_depth; /** Time check-point. */ __u64 tc_check_time; /** Deadline of a class */ __u64 tc_deadline; /** * Time residue: the remainder of elapsed time * divided by nsecs when dequeue a request. */ __u64 tc_nsecs_resid; /** List of queued requests. */ struct list_head tc_list; /** Node in binary heap. */ struct binheap_node tc_node; /** Whether the client is in heap. */ bool tc_in_heap; /** Sequence of the newest rule. */ __u32 tc_rule_sequence; /** * Linkage into LRU list. Protected bucket lock of * nrs_tbf_head::th_cli_hash. */ struct list_head tc_lru; }; #define MAX_TBF_NAME (16) enum nrs_rule_flags { NTRS_STOPPING = 0x00000001, NTRS_DEFAULT = 0x00000002, NTRS_REALTIME = 0x00000004, }; struct nrs_tbf_rule { /** Name of the rule. */ char tr_name[MAX_TBF_NAME]; /** Head belongs to. */ struct nrs_tbf_head *tr_head; /** Likage to head. */ struct list_head tr_linkage; /** Nid list of the rule. */ struct list_head tr_nids; /** Nid list string of the rule.*/ char *tr_nids_str; /** Jobid list of the rule. */ struct list_head tr_jobids; /** Jobid list string of the rule.*/ char *tr_jobids_str; /** uid/gid list of the rule. */ struct list_head tr_ids; /** uid/gid list string of the rule. */ char *tr_ids_str; /** Opcode bitmap of the rule. */ unsigned long *tr_opcodes; u32 tr_opcodes_cnt; /** Opcode list string of the rule.*/ char *tr_opcodes_str; /** Condition list of the rule.*/ struct list_head tr_conds; /** Generic condition string of the rule. */ char *tr_conds_str; /** RPC/s limit. */ __u64 tr_rpc_rate; /** Time to wait for next token. */ u64 tr_nsecs_per_rpc; /** Token bucket depth. */ __u64 tr_depth; /** Lock to protect the list of clients. */ spinlock_t tr_rule_lock; /** List of client. */ struct list_head tr_cli_list; /** Flags of the rule. */ enum nrs_rule_flags tr_flags; /** Usage Reference count taken on the rule. */ atomic_t tr_ref; /** Generation of the rule. */ __u64 tr_generation; }; struct nrs_tbf_ops { char *o_name; int (*o_startup)(struct ptlrpc_nrs_policy *, struct nrs_tbf_head *); struct nrs_tbf_client *(*o_cli_find)(struct nrs_tbf_head *, struct ptlrpc_request *); struct nrs_tbf_client *(*o_cli_findadd)(struct nrs_tbf_head *, struct nrs_tbf_client *); void (*o_cli_put)(struct nrs_tbf_head *, struct nrs_tbf_client *); void (*o_cli_init)(struct nrs_tbf_client *, struct ptlrpc_request *); int (*o_rule_init)(struct ptlrpc_nrs_policy *, struct nrs_tbf_rule *, struct nrs_tbf_cmd *); int (*o_rule_dump)(struct nrs_tbf_rule *, struct seq_file *); int (*o_rule_match)(struct nrs_tbf_rule *, struct nrs_tbf_client *); void (*o_rule_fini)(struct nrs_tbf_rule *); }; #define NRS_TBF_TYPE_JOBID "jobid" #define NRS_TBF_TYPE_NID "nid" #define NRS_TBF_TYPE_OPCODE "opcode" #define NRS_TBF_TYPE_GENERIC "generic" #define NRS_TBF_TYPE_UID "uid" #define NRS_TBF_TYPE_GID "gid" #define NRS_TBF_TYPE_MAX_LEN 20 struct nrs_tbf_type { const char *ntt_name; enum nrs_tbf_flag ntt_flag; struct nrs_tbf_ops *ntt_ops; }; struct nrs_tbf_bucket { /** * LRU list, updated on each access to client. Protected by * bucket lock of nrs_tbf_head::th_cli_hash. */ struct list_head ntb_lru; }; /** * Private data structure for the TBF policy */ struct nrs_tbf_head { /** * Resource object for policy instance. */ struct ptlrpc_nrs_resource th_res; /** * List of rules. */ struct list_head th_list; /** * Lock to protect the list of rules. */ spinlock_t th_rule_lock; /** * Generation of rules. */ atomic_t th_rule_sequence; /** * Default rule. */ struct nrs_tbf_rule *th_rule; /** * Timer for next token. */ struct hrtimer th_timer; /** * Deadline of the timer. */ __u64 th_deadline; /** * Sequence of requests. */ __u64 th_sequence; /** * Heap of queues. */ struct binheap *th_binheap; /** * Hash of clients. */ struct cfs_hash *th_cli_hash; /** * Type of TBF policy. */ char th_type[NRS_TBF_TYPE_MAX_LEN + 1]; /** * Rule operations. */ struct nrs_tbf_ops *th_ops; /** * Flag of type. */ __u32 th_type_flag; /** * Index of bucket on hash table while purging. */ int th_purge_start; }; enum nrs_tbf_cmd_type { NRS_CTL_TBF_START_RULE = 0, NRS_CTL_TBF_STOP_RULE, NRS_CTL_TBF_CHANGE_RULE, }; struct nrs_tbf_cmd { enum nrs_tbf_cmd_type tc_cmd; char *tc_name; union { struct nrs_tbf_cmd_start { __u64 ts_rpc_rate; struct list_head ts_nids; char *ts_nids_str; struct list_head ts_jobids; char *ts_jobids_str; struct list_head ts_ids; char *ts_ids_str; char *ts_opcodes_str; struct list_head ts_conds; char *ts_conds_str; __u32 ts_valid_type; enum nrs_rule_flags ts_rule_flags; char *ts_next_name; } tc_start; struct nrs_tbf_cmd_change { __u64 tc_rpc_rate; char *tc_next_name; } tc_change; } u; }; enum nrs_tbf_field { NRS_TBF_FIELD_NID, NRS_TBF_FIELD_JOBID, NRS_TBF_FIELD_OPCODE, NRS_TBF_FIELD_UID, NRS_TBF_FIELD_GID, NRS_TBF_FIELD_MAX }; struct nrs_tbf_expression { enum nrs_tbf_field te_field; struct list_head te_cond; unsigned long *te_opcodes; u32 te_opcodes_cnt; struct list_head te_linkage; }; struct nrs_tbf_conjunction { /** * link to disjunction. */ struct list_head tc_linkage; /** * list of logical conjunction */ struct list_head tc_expressions; }; struct nrs_tbf_req { /** * Linkage to queue. */ struct list_head tr_list; /** * Sequence of the request. */ __u64 tr_sequence; }; /** * TBF policy operations. * * Read the the data of a TBF policy. */ #define NRS_CTL_TBF_RD_RULE PTLRPC_NRS_CTL_POL_SPEC_01 /** * Write the the data of a TBF policy. */ #define NRS_CTL_TBF_WR_RULE PTLRPC_NRS_CTL_POL_SPEC_02 /** * Read the TBF policy type preset by proc entry "nrs_policies". */ #define NRS_CTL_TBF_RD_TYPE_FLAG PTLRPC_NRS_CTL_POL_SPEC_03 /** @} tbf */ #endif