Lines Matching refs:sctx

63 	struct switch_ctx *sctx;  in alloc_switch_ctx()  local
65 sctx = kzalloc(struct_size(sctx, path_list, nr_paths), GFP_KERNEL); in alloc_switch_ctx()
66 if (!sctx) in alloc_switch_ctx()
69 sctx->ti = ti; in alloc_switch_ctx()
70 sctx->region_size = region_size; in alloc_switch_ctx()
72 ti->private = sctx; in alloc_switch_ctx()
74 return sctx; in alloc_switch_ctx()
79 struct switch_ctx *sctx = ti->private; in alloc_region_table() local
83 if (!(sctx->region_size & (sctx->region_size - 1))) in alloc_region_table()
84 sctx->region_size_bits = __ffs(sctx->region_size); in alloc_region_table()
86 sctx->region_size_bits = -1; in alloc_region_table()
88 sctx->region_table_entry_bits = 1; in alloc_region_table()
89 while (sctx->region_table_entry_bits < sizeof(region_table_slot_t) * 8 && in alloc_region_table()
90 (region_table_slot_t)1 << sctx->region_table_entry_bits < nr_paths) in alloc_region_table()
91 sctx->region_table_entry_bits++; in alloc_region_table()
93 sctx->region_entries_per_slot = (sizeof(region_table_slot_t) * 8) / sctx->region_table_entry_bits; in alloc_region_table()
94 if (!(sctx->region_entries_per_slot & (sctx->region_entries_per_slot - 1))) in alloc_region_table()
95 sctx->region_entries_per_slot_bits = __ffs(sctx->region_entries_per_slot); in alloc_region_table()
97 sctx->region_entries_per_slot_bits = -1; in alloc_region_table()
99 if (sector_div(nr_regions, sctx->region_size)) in alloc_region_table()
106 sctx->nr_regions = nr_regions; in alloc_region_table()
109 if (sector_div(nr_slots, sctx->region_entries_per_slot)) in alloc_region_table()
117 sctx->region_table = vmalloc(array_size(nr_slots, in alloc_region_table()
119 if (!sctx->region_table) { in alloc_region_table()
127 static void switch_get_position(struct switch_ctx *sctx, unsigned long region_nr, in switch_get_position() argument
130 if (sctx->region_entries_per_slot_bits >= 0) { in switch_get_position()
131 *region_index = region_nr >> sctx->region_entries_per_slot_bits; in switch_get_position()
132 *bit = region_nr & (sctx->region_entries_per_slot - 1); in switch_get_position()
134 *region_index = region_nr / sctx->region_entries_per_slot; in switch_get_position()
135 *bit = region_nr % sctx->region_entries_per_slot; in switch_get_position()
138 *bit *= sctx->region_table_entry_bits; in switch_get_position()
141 static unsigned int switch_region_table_read(struct switch_ctx *sctx, unsigned long region_nr) in switch_region_table_read() argument
146 switch_get_position(sctx, region_nr, &region_index, &bit); in switch_region_table_read()
148 return (READ_ONCE(sctx->region_table[region_index]) >> bit) & in switch_region_table_read()
149 ((1 << sctx->region_table_entry_bits) - 1); in switch_region_table_read()
155 static unsigned int switch_get_path_nr(struct switch_ctx *sctx, sector_t offset) in switch_get_path_nr() argument
161 if (sctx->region_size_bits >= 0) in switch_get_path_nr()
162 p >>= sctx->region_size_bits; in switch_get_path_nr()
164 sector_div(p, sctx->region_size); in switch_get_path_nr()
166 path_nr = switch_region_table_read(sctx, p); in switch_get_path_nr()
169 if (unlikely(path_nr >= sctx->nr_paths)) in switch_get_path_nr()
175 static void switch_region_table_write(struct switch_ctx *sctx, unsigned long region_nr, in switch_region_table_write() argument
182 switch_get_position(sctx, region_nr, &region_index, &bit); in switch_region_table_write()
184 pte = sctx->region_table[region_index]; in switch_region_table_write()
185 pte &= ~((((region_table_slot_t)1 << sctx->region_table_entry_bits) - 1) << bit); in switch_region_table_write()
187 sctx->region_table[region_index] = pte; in switch_region_table_write()
193 static void initialise_region_table(struct switch_ctx *sctx) in initialise_region_table() argument
198 for (region_nr = 0; region_nr < sctx->nr_regions; region_nr++) { in initialise_region_table()
199 switch_region_table_write(sctx, region_nr, path_nr); in initialise_region_table()
200 if (++path_nr >= sctx->nr_paths) in initialise_region_table()
207 struct switch_ctx *sctx = ti->private; in parse_path() local
212 &sctx->path_list[sctx->nr_paths].dmdev); in parse_path()
220 dm_put_device(ti, sctx->path_list[sctx->nr_paths].dmdev); in parse_path()
224 sctx->path_list[sctx->nr_paths].start = start; in parse_path()
226 sctx->nr_paths++; in parse_path()
236 struct switch_ctx *sctx = ti->private; in switch_dtr() local
238 while (sctx->nr_paths--) in switch_dtr()
239 dm_put_device(ti, sctx->path_list[sctx->nr_paths].dmdev); in switch_dtr()
241 vfree(sctx->region_table); in switch_dtr()
242 kfree(sctx); in switch_dtr()
261 struct switch_ctx *sctx; in switch_ctr() local
287 sctx = alloc_switch_ctx(ti, nr_paths, region_size); in switch_ctr()
288 if (!sctx) { in switch_ctr()
307 initialise_region_table(sctx); in switch_ctr()
322 struct switch_ctx *sctx = ti->private; in switch_map() local
324 unsigned int path_nr = switch_get_path_nr(sctx, offset); in switch_map()
326 bio_set_dev(bio, sctx->path_list[path_nr].dmdev->bdev); in switch_map()
327 bio->bi_iter.bi_sector = sctx->path_list[path_nr].start + offset; in switch_map()
374 static int process_set_region_mappings(struct switch_ctx *sctx, in process_set_region_mappings() argument
414 unlikely(region_index + num_write >= sctx->nr_regions)) { in process_set_region_mappings()
416 region_index, num_write, sctx->nr_regions); in process_set_region_mappings()
422 path_nr = switch_region_table_read(sctx, region_index - cycle_length); in process_set_region_mappings()
423 switch_region_table_write(sctx, region_index, path_nr); in process_set_region_mappings()
450 if (unlikely(region_index >= sctx->nr_regions)) { in process_set_region_mappings()
451 DMWARN("invalid set_region_mappings region number: %lu >= %lu", region_index, sctx->nr_regions); in process_set_region_mappings()
454 if (unlikely(path_nr >= sctx->nr_paths)) { in process_set_region_mappings()
455 DMWARN("invalid set_region_mappings device: %lu >= %u", path_nr, sctx->nr_paths); in process_set_region_mappings()
459 switch_region_table_write(sctx, region_index, path_nr); in process_set_region_mappings()
475 struct switch_ctx *sctx = ti->private; in switch_message() local
481 r = process_set_region_mappings(sctx, argc, argv); in switch_message()
493 struct switch_ctx *sctx = ti->private; in switch_status() local
503 DMEMIT("%u %u 0", sctx->nr_paths, sctx->region_size); in switch_status()
504 for (path_nr = 0; path_nr < sctx->nr_paths; path_nr++) in switch_status()
505 DMEMIT(" %s %llu", sctx->path_list[path_nr].dmdev->name, in switch_status()
506 (unsigned long long)sctx->path_list[path_nr].start); in switch_status()
522 struct switch_ctx *sctx = ti->private; in switch_prepare_ioctl() local
525 path_nr = switch_get_path_nr(sctx, 0); in switch_prepare_ioctl()
527 *bdev = sctx->path_list[path_nr].dmdev->bdev; in switch_prepare_ioctl()
532 if (ti->len + sctx->path_list[path_nr].start != in switch_prepare_ioctl()
541 struct switch_ctx *sctx = ti->private; in switch_iterate_devices() local
545 for (path_nr = 0; path_nr < sctx->nr_paths; path_nr++) { in switch_iterate_devices()
546 r = fn(ti, sctx->path_list[path_nr].dmdev, in switch_iterate_devices()
547 sctx->path_list[path_nr].start, ti->len, data); in switch_iterate_devices()