Skip to content

Commit f177940

Browse files
jthornbersnitm
authored andcommitted
dm cache metadata: switch to using the new cursor api for loading metadata
This change offers a pretty significant performance improvement. Signed-off-by: Joe Thornber <[email protected]> Signed-off-by: Mike Snitzer <[email protected]>
1 parent fdd1315 commit f177940

File tree

1 file changed

+80
-23
lines changed

1 file changed

+80
-23
lines changed

drivers/md/dm-cache-metadata.c

Lines changed: 80 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@ struct dm_cache_metadata {
140140
* the device.
141141
*/
142142
bool fail_io:1;
143+
144+
/*
145+
* These structures are used when loading metadata. They're too
146+
* big to put on the stack.
147+
*/
148+
struct dm_array_cursor mapping_cursor;
149+
struct dm_array_cursor hint_cursor;
143150
};
144151

145152
/*-------------------------------------------------------------------
@@ -1171,31 +1178,37 @@ static bool hints_array_available(struct dm_cache_metadata *cmd,
11711178
hints_array_initialized(cmd);
11721179
}
11731180

1174-
static int __load_mapping(void *context, uint64_t cblock, void *leaf)
1181+
static int __load_mapping(struct dm_cache_metadata *cmd,
1182+
uint64_t cb, bool hints_valid,
1183+
struct dm_array_cursor *mapping_cursor,
1184+
struct dm_array_cursor *hint_cursor,
1185+
load_mapping_fn fn, void *context)
11751186
{
11761187
int r = 0;
1177-
bool dirty;
1178-
__le64 value;
1179-
__le32 hint_value = 0;
1188+
1189+
__le64 mapping;
1190+
__le32 hint = 0;
1191+
1192+
__le64 *mapping_value_le;
1193+
__le32 *hint_value_le;
1194+
11801195
dm_oblock_t oblock;
11811196
unsigned flags;
1182-
struct thunk *thunk = context;
1183-
struct dm_cache_metadata *cmd = thunk->cmd;
11841197

1185-
memcpy(&value, leaf, sizeof(value));
1186-
unpack_value(value, &oblock, &flags);
1198+
dm_array_cursor_get_value(mapping_cursor, (void **) &mapping_value_le);
1199+
memcpy(&mapping, mapping_value_le, sizeof(mapping));
1200+
unpack_value(mapping, &oblock, &flags);
11871201

11881202
if (flags & M_VALID) {
1189-
if (thunk->hints_valid) {
1190-
r = dm_array_get_value(&cmd->hint_info, cmd->hint_root,
1191-
cblock, &hint_value);
1192-
if (r && r != -ENODATA)
1193-
return r;
1203+
if (hints_valid) {
1204+
dm_array_cursor_get_value(hint_cursor, (void **) &hint_value_le);
1205+
memcpy(&hint, hint_value_le, sizeof(hint));
11941206
}
11951207

1196-
dirty = thunk->respect_dirty_flags ? (flags & M_DIRTY) : true;
1197-
r = thunk->fn(thunk->context, oblock, to_cblock(cblock),
1198-
dirty, le32_to_cpu(hint_value), thunk->hints_valid);
1208+
r = fn(context, oblock, to_cblock(cb), flags & M_DIRTY,
1209+
le32_to_cpu(hint), hints_valid);
1210+
if (r)
1211+
DMERR("policy couldn't load cblock");
11991212
}
12001213

12011214
return r;
@@ -1205,16 +1218,60 @@ static int __load_mappings(struct dm_cache_metadata *cmd,
12051218
struct dm_cache_policy *policy,
12061219
load_mapping_fn fn, void *context)
12071220
{
1208-
struct thunk thunk;
1221+
int r;
1222+
uint64_t cb;
12091223

1210-
thunk.fn = fn;
1211-
thunk.context = context;
1224+
bool hints_valid = hints_array_available(cmd, policy);
12121225

1213-
thunk.cmd = cmd;
1214-
thunk.respect_dirty_flags = cmd->clean_when_opened;
1215-
thunk.hints_valid = hints_array_available(cmd, policy);
1226+
if (from_cblock(cmd->cache_blocks) == 0)
1227+
/* Nothing to do */
1228+
return 0;
12161229

1217-
return dm_array_walk(&cmd->info, cmd->root, __load_mapping, &thunk);
1230+
r = dm_array_cursor_begin(&cmd->info, cmd->root, &cmd->mapping_cursor);
1231+
if (r)
1232+
return r;
1233+
1234+
if (hints_valid) {
1235+
r = dm_array_cursor_begin(&cmd->hint_info, cmd->hint_root, &cmd->hint_cursor);
1236+
if (r) {
1237+
dm_array_cursor_end(&cmd->mapping_cursor);
1238+
return r;
1239+
}
1240+
}
1241+
1242+
for (cb = 0; ; cb++) {
1243+
r = __load_mapping(cmd, cb, hints_valid,
1244+
&cmd->mapping_cursor, &cmd->hint_cursor,
1245+
fn, context);
1246+
if (r)
1247+
goto out;
1248+
1249+
/*
1250+
* We need to break out before we move the cursors.
1251+
*/
1252+
if (cb >= (from_cblock(cmd->cache_blocks) - 1))
1253+
break;
1254+
1255+
r = dm_array_cursor_next(&cmd->mapping_cursor);
1256+
if (r) {
1257+
DMERR("dm_array_cursor_next for mapping failed");
1258+
goto out;
1259+
}
1260+
1261+
if (hints_valid) {
1262+
r = dm_array_cursor_next(&cmd->hint_cursor);
1263+
if (r) {
1264+
DMERR("dm_array_cursor_next for hint failed");
1265+
goto out;
1266+
}
1267+
}
1268+
}
1269+
out:
1270+
dm_array_cursor_end(&cmd->mapping_cursor);
1271+
if (hints_valid)
1272+
dm_array_cursor_end(&cmd->hint_cursor);
1273+
1274+
return r;
12181275
}
12191276

12201277
int dm_cache_load_mappings(struct dm_cache_metadata *cmd,

0 commit comments

Comments
 (0)