]> git.proxmox.com Git - ceph.git/blame - ceph/src/spdk/ocf/src/utils/utils_part.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / ocf / src / utils / utils_part.c
CommitLineData
9f95a23c
TL
1/*
2 * Copyright(c) 2012-2018 Intel Corporation
3 * SPDX-License-Identifier: BSD-3-Clause-Clear
4 */
5
6#include "ocf/ocf.h"
7#include "../ocf_cache_priv.h"
8#include "../ocf_request.h"
9#include "../metadata/metadata.h"
10#include "../engine/cache_engine.h"
11#include "../eviction/ops.h"
12#include "utils_part.h"
13
14static struct ocf_lst_entry *ocf_part_lst_getter_valid(
15 struct ocf_cache *cache, ocf_cache_line_t idx)
16{
17 ENV_BUG_ON(idx > OCF_IO_CLASS_MAX);
18 return &cache->user_parts[idx].lst_valid;
19}
20
21
22static int ocf_part_lst_cmp_valid(struct ocf_cache *cache,
23 struct ocf_lst_entry *e1, struct ocf_lst_entry *e2)
24{
25 struct ocf_user_part *p1 = container_of(e1, struct ocf_user_part,
26 lst_valid);
27 struct ocf_user_part *p2 = container_of(e2, struct ocf_user_part,
28 lst_valid);
29 size_t p1_size = ocf_cache_is_device_attached(cache) ?
30 p1->runtime->curr_size : 0;
31 size_t p2_size = ocf_cache_is_device_attached(cache) ?
32 p2->runtime->curr_size : 0;
33
34 int v1 = p1->config->priority;
35 int v2 = p2->config->priority;
36
37 /*
38 * If partition is invalid the priority depends on current size:
39 * 1. Partition is empty - move to the end of list
40 * 2. Partition is not empty - move to the beginning of the list. This
41 * partition will be evicted first
42 */
43
44 if (p1->config->priority == OCF_IO_CLASS_PRIO_PINNED)
45 p1->config->flags.eviction = false;
46 else
47 p1->config->flags.eviction = true;
48
49 if (p2->config->priority == OCF_IO_CLASS_PRIO_PINNED)
50 p2->config->flags.eviction = false;
51 else
52 p2->config->flags.eviction = true;
53
54 if (!p1->config->flags.valid) {
55 if (p1_size) {
56 v1 = SHRT_MAX;
57 p1->config->flags.eviction = true;
58 } else {
59 v1 = SHRT_MIN;
60 p1->config->flags.eviction = false;
61 }
62 }
63
64 if (!p2->config->flags.valid) {
65 if (p2_size) {
66 v2 = SHRT_MAX;
f67539c2 67 p2->config->flags.eviction = true;
9f95a23c
TL
68 } else {
69 v2 = SHRT_MIN;
70 p2->config->flags.eviction = false;
71 }
72 }
73
74 if (v1 == v2) {
75 v1 = p1 - cache->user_parts;
76 v2 = p2 - cache->user_parts;
77 }
78
79 return v2 - v1;
80}
81
f67539c2 82void ocf_part_init(struct ocf_cache *cache)
9f95a23c
TL
83{
84 ocf_lst_init(cache, &cache->lst_part, OCF_IO_CLASS_MAX,
85 ocf_part_lst_getter_valid, ocf_part_lst_cmp_valid);
9f95a23c
TL
86}
87
88void ocf_part_move(struct ocf_request *req)
89{
90 struct ocf_cache *cache = req->cache;
91 struct ocf_map_info *entry;
92 ocf_cache_line_t line;
93 ocf_part_id_t id_old, id_new;
94 uint32_t i;
95 ocf_cleaning_t type = cache->conf_meta->cleaning_policy_type;
96
97 ENV_BUG_ON(type >= ocf_cleaning_max);
98
99 entry = &req->map[0];
100 for (i = 0; i < req->core_line_count; i++, entry++) {
101 if (!entry->re_part) {
102 /* Changing partition not required */
103 continue;
104 }
105
106 if (entry->status != LOOKUP_HIT) {
107 /* No HIT */
108 continue;
109 }
110
111 line = entry->coll_idx;
112 id_old = ocf_metadata_get_partition_id(cache, line);
113 id_new = req->part_id;
114
115 ENV_BUG_ON(id_old >= OCF_IO_CLASS_MAX ||
116 id_new >= OCF_IO_CLASS_MAX);
117
118 if (id_old == id_new) {
119 /* Partition of the request and cache line is the same,
120 * no need to change partition
121 */
122 continue;
123 }
124
125 /* Remove from old eviction */
126 ocf_eviction_purge_cache_line(cache, line);
127
128 if (metadata_test_dirty(cache, line)) {
129 /*
130 * Remove cline from cleaning - this if for ioclass
131 * oriented cleaning policy (e.g. ALRU).
132 * TODO: Consider adding update_cache_line() ops
133 * to cleaning policy to let policies handle this.
134 */
135 if (cleaning_policy_ops[type].purge_cache_block)
136 cleaning_policy_ops[type].
137 purge_cache_block(cache, line);
138 }
139
140 /* Let's change partition */
141 ocf_metadata_remove_from_partition(cache, id_old, line);
142 ocf_metadata_add_to_partition(cache, id_new, line);
143
144 /* Add to new eviction */
145 ocf_eviction_init_cache_line(cache, line, id_new);
146 ocf_eviction_set_hot_cache_line(cache, line);
147
148 /* Check if cache line is dirty. If yes then need to change
149 * cleaning policy and update partition dirty clines
150 * statistics.
151 */
152 if (metadata_test_dirty(cache, line)) {
153 /* Add cline back to cleaning policy */
154 if (cleaning_policy_ops[type].set_hot_cache_line)
155 cleaning_policy_ops[type].
156 set_hot_cache_line(cache, line);
157
f67539c2 158 env_atomic_inc(&req->core->runtime_meta->
9f95a23c 159 part_counters[id_new].dirty_clines);
f67539c2 160 env_atomic_dec(&req->core->runtime_meta->
9f95a23c
TL
161 part_counters[id_old].dirty_clines);
162 }
163
f67539c2 164 env_atomic_inc(&req->core->runtime_meta->
9f95a23c 165 part_counters[id_new].cached_clines);
f67539c2 166 env_atomic_dec(&req->core->runtime_meta->
9f95a23c
TL
167 part_counters[id_old].cached_clines);
168
169 /* DONE */
170 }
171}
172
173void ocf_part_set_valid(struct ocf_cache *cache, ocf_part_id_t id,
174 bool valid)
175{
176 struct ocf_user_part *part = &cache->user_parts[id];
177
178 if (valid ^ part->config->flags.valid) {
179 if (valid) {
180 part->config->flags.valid = true;
181 cache->conf_meta->valid_parts_no++;
182 } else {
183 part->config->flags.valid = false;
184 cache->conf_meta->valid_parts_no--;
185 part->config->priority = OCF_IO_CLASS_PRIO_LOWEST;
186 part->config->min_size = 0;
187 part->config->max_size = PARTITION_SIZE_MAX;
188 ENV_BUG_ON(env_strncpy(part->config->name, sizeof(part->config->name),
189 "Inactive", 9));
190 }
191 }
192}