]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/ocf/src/promotion/promotion.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / ocf / src / promotion / promotion.c
1 /*
2 * Copyright(c) 2019 Intel Corporation
3 * SPDX-License-Identifier: BSD-3-Clause-Clear
4 */
5
6 #include "../metadata/metadata.h"
7
8 #include "promotion.h"
9 #include "ops.h"
10 #include "nhit/nhit.h"
11
12 struct promotion_policy_ops ocf_promotion_policies[ocf_promotion_max] = {
13 [ocf_promotion_always] = {
14 .name = "always",
15 },
16 [ocf_promotion_nhit] = {
17 .name = "nhit",
18 .setup = nhit_setup,
19 .init = nhit_init,
20 .deinit = nhit_deinit,
21 .set_param = nhit_set_param,
22 .get_param = nhit_get_param,
23 .req_purge = nhit_req_purge,
24 .req_should_promote = nhit_req_should_promote,
25 },
26 };
27
28 ocf_error_t ocf_promotion_init(ocf_cache_t cache, ocf_promotion_t type)
29 {
30 ocf_promotion_policy_t policy;
31 ocf_error_t result = 0;
32
33 ENV_BUG_ON(type >= ocf_promotion_max);
34
35 policy = env_vmalloc(sizeof(*policy));
36 if (!policy)
37 return -OCF_ERR_NO_MEM;
38
39 policy->type = type;
40 policy->owner = cache;
41 policy->config =
42 (void *)&cache->conf_meta->promotion[type].data;
43 cache->promotion_policy = policy;
44
45 if (ocf_promotion_policies[type].init)
46 result = ocf_promotion_policies[type].init(cache);
47
48 if (result) {
49 env_vfree(cache->promotion_policy);
50 cache->promotion_policy = NULL;
51 ocf_cache_log(cache, log_info,
52 "Policy '%s' failed to initialize\n",
53 ocf_promotion_policies[type].name);
54 } else {
55 ocf_cache_log(cache, log_info,
56 "Policy '%s' initialized successfully\n",
57 ocf_promotion_policies[type].name);
58 }
59
60 return result;
61 }
62
63 void ocf_promotion_deinit(ocf_promotion_policy_t policy)
64 {
65 ocf_promotion_t type = policy->type;
66
67 ENV_BUG_ON(type >= ocf_promotion_max);
68
69 if (ocf_promotion_policies[type].deinit)
70 ocf_promotion_policies[type].deinit(policy);
71
72 env_vfree(policy);
73 }
74
75 ocf_error_t ocf_promotion_set_policy(ocf_promotion_policy_t policy,
76 ocf_promotion_t type)
77 {
78 ocf_error_t result = 0;
79 ocf_cache_t cache = policy->owner;
80 ocf_promotion_t prev_policy;
81
82 if (type >= ocf_promotion_max)
83 return -OCF_ERR_INVAL;
84
85 prev_policy = cache->conf_meta->promotion_policy_type;
86
87 if (type == prev_policy) {
88 ocf_cache_log(cache, log_info, "Promotion policy '%s' is already set\n",
89 ocf_promotion_policies[type].name);
90 return 0;
91 }
92
93 if (ocf_promotion_policies[prev_policy].deinit)
94 ocf_promotion_policies[prev_policy].deinit(policy);
95
96 cache->conf_meta->promotion_policy_type = type;
97 policy->type = type;
98
99 if (ocf_promotion_policies[type].init)
100 result = ocf_promotion_policies[type].init(cache);
101
102 if (result) {
103 ocf_cache_log(cache, log_err,
104 "Error switching to new promotion policy\n");
105 ocf_cache_log(cache, log_err,
106 "Falling back to 'always' promotion policy\n");
107 cache->conf_meta->promotion_policy_type = ocf_promotion_always;
108 policy->type = ocf_promotion_always;
109 } else {
110 ocf_cache_log(cache, log_info,
111 "Switched to '%s' promotion policy\n",
112 ocf_promotion_policies[type].name);
113 }
114
115 return result;
116 }
117
118 ocf_error_t ocf_promotion_set_param(ocf_cache_t cache, ocf_promotion_t type,
119 uint8_t param_id, uint32_t param_value)
120 {
121 ocf_error_t result = -OCF_ERR_INVAL;
122
123 ENV_BUG_ON(type >= ocf_promotion_max);
124
125 if (ocf_promotion_policies[type].set_param) {
126 result = ocf_promotion_policies[type].set_param(cache, param_id,
127 param_value);
128 }
129
130 return result;
131 }
132
133 ocf_error_t ocf_promotion_get_param(ocf_cache_t cache, ocf_promotion_t type,
134 uint8_t param_id, uint32_t *param_value)
135 {
136 ocf_error_t result = -OCF_ERR_INVAL;
137
138 ENV_BUG_ON(type >= ocf_promotion_max);
139
140 if (ocf_promotion_policies[type].get_param) {
141 result = ocf_promotion_policies[type].get_param(cache, param_id,
142 param_value);
143 }
144
145 return result;
146 }
147
148 void ocf_promotion_req_purge(ocf_promotion_policy_t policy,
149 struct ocf_request *req)
150 {
151 ocf_promotion_t type = policy->type;
152
153 ENV_BUG_ON(type >= ocf_promotion_max);
154
155 if (ocf_promotion_policies[type].req_purge)
156 ocf_promotion_policies[type].req_purge(policy, req);
157 }
158
159 bool ocf_promotion_req_should_promote(ocf_promotion_policy_t policy,
160 struct ocf_request *req)
161 {
162 ocf_promotion_t type = policy->type;
163 bool result = true;
164
165 ENV_BUG_ON(type >= ocf_promotion_max);
166
167 if (ocf_promotion_policies[type].req_should_promote) {
168 result = ocf_promotion_policies[type].req_should_promote(policy,
169 req);
170 }
171
172 return result;
173 }
174