diff options
author | Ilya Dryomov <ilya.dryomov@inktank.com> | 2014-01-31 10:54:26 -0500 |
---|---|---|
committer | Yan, Zheng <zheng.z.yan@intel.com> | 2014-04-02 22:33:50 -0400 |
commit | 9d521470a40f16110bd31018034155c60c1a1275 (patch) | |
tree | 0dd56756c47839cd9605262ddca0f91c12c07c67 /net/ceph | |
parent | 455c6fdbd219161bd09b1165f11699d6d73de11c (diff) |
libceph: a per-osdc crush scratch buffer
With the addition of erasure coding support in the future, scratch
variable-length array in crush_do_rule_ary() is going to grow to at
least 200 bytes on average, on top of another 128 bytes consumed by
rawosd/osd arrays in the call chain. Replace it with a buffer inside
struct osdmap and a mutex. This shouldn't result in any contention,
because all osd requests were already serialized by request_mutex at
that point; the only unlocked caller was ceph_ioctl_get_dataloc().
Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com>
Reviewed-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'net/ceph')
-rw-r--r-- | net/ceph/osdmap.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index aade4a5c1c07..9d1aaa24def6 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c | |||
@@ -698,7 +698,9 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) | |||
698 | map = kzalloc(sizeof(*map), GFP_NOFS); | 698 | map = kzalloc(sizeof(*map), GFP_NOFS); |
699 | if (map == NULL) | 699 | if (map == NULL) |
700 | return ERR_PTR(-ENOMEM); | 700 | return ERR_PTR(-ENOMEM); |
701 | |||
701 | map->pg_temp = RB_ROOT; | 702 | map->pg_temp = RB_ROOT; |
703 | mutex_init(&map->crush_scratch_mutex); | ||
702 | 704 | ||
703 | ceph_decode_16_safe(p, end, version, bad); | 705 | ceph_decode_16_safe(p, end, version, bad); |
704 | if (version > 6) { | 706 | if (version > 6) { |
@@ -1142,14 +1144,20 @@ int ceph_oloc_oid_to_pg(struct ceph_osdmap *osdmap, | |||
1142 | } | 1144 | } |
1143 | EXPORT_SYMBOL(ceph_oloc_oid_to_pg); | 1145 | EXPORT_SYMBOL(ceph_oloc_oid_to_pg); |
1144 | 1146 | ||
1145 | static int crush_do_rule_ary(const struct crush_map *map, int ruleno, int x, | 1147 | static int do_crush(struct ceph_osdmap *map, int ruleno, int x, |
1146 | int *result, int result_max, | 1148 | int *result, int result_max, |
1147 | const __u32 *weight, int weight_max) | 1149 | const __u32 *weight, int weight_max) |
1148 | { | 1150 | { |
1149 | int scratch[result_max * 3]; | 1151 | int r; |
1152 | |||
1153 | BUG_ON(result_max > CEPH_PG_MAX_SIZE); | ||
1154 | |||
1155 | mutex_lock(&map->crush_scratch_mutex); | ||
1156 | r = crush_do_rule(map->crush, ruleno, x, result, result_max, | ||
1157 | weight, weight_max, map->crush_scratch_ary); | ||
1158 | mutex_unlock(&map->crush_scratch_mutex); | ||
1150 | 1159 | ||
1151 | return crush_do_rule(map, ruleno, x, result, result_max, | 1160 | return r; |
1152 | weight, weight_max, scratch); | ||
1153 | } | 1161 | } |
1154 | 1162 | ||
1155 | /* | 1163 | /* |
@@ -1205,9 +1213,8 @@ static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid, | |||
1205 | pool->pgp_num_mask) + | 1213 | pool->pgp_num_mask) + |
1206 | (unsigned)pgid.pool; | 1214 | (unsigned)pgid.pool; |
1207 | } | 1215 | } |
1208 | r = crush_do_rule_ary(osdmap->crush, ruleno, pps, | 1216 | r = do_crush(osdmap, ruleno, pps, osds, min_t(int, pool->size, *num), |
1209 | osds, min_t(int, pool->size, *num), | 1217 | osdmap->osd_weight, osdmap->max_osd); |
1210 | osdmap->osd_weight, osdmap->max_osd); | ||
1211 | if (r < 0) { | 1218 | if (r < 0) { |
1212 | pr_err("error %d from crush rule: pool %lld ruleset %d type %d" | 1219 | pr_err("error %d from crush rule: pool %lld ruleset %d type %d" |
1213 | " size %d\n", r, pgid.pool, pool->crush_ruleset, | 1220 | " size %d\n", r, pgid.pool, pool->crush_ruleset, |