aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph
diff options
context:
space:
mode:
authorIlya Dryomov <ilya.dryomov@inktank.com>2014-01-31 10:54:26 -0500
committerYan, Zheng <zheng.z.yan@intel.com>2014-04-02 22:33:50 -0400
commit9d521470a40f16110bd31018034155c60c1a1275 (patch)
tree0dd56756c47839cd9605262ddca0f91c12c07c67 /net/ceph
parent455c6fdbd219161bd09b1165f11699d6d73de11c (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.c25
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}
1143EXPORT_SYMBOL(ceph_oloc_oid_to_pg); 1145EXPORT_SYMBOL(ceph_oloc_oid_to_pg);
1144 1146
1145static int crush_do_rule_ary(const struct crush_map *map, int ruleno, int x, 1147static 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,