Skip to content

Commit 3b4168d

Browse files
lxbszidryomov
authored andcommitted
ceph: send client provided metric flags in client metadata
Send metric flags to the MDS, indicating what metrics the client supports. Currently that consists of cap statistics, and read, write and metadata latencies. URL: https://tracker.ceph.com/issues/43435 Signed-off-by: Xiubo Li <xiubli@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
1 parent 18f473b commit 3b4168d

2 files changed

Lines changed: 71 additions & 2 deletions

File tree

fs/ceph/mds_client.c

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,48 @@ static int encode_supported_features(void **p, void *end)
11941194
return 0;
11951195
}
11961196

1197+
static const unsigned char metric_bits[] = CEPHFS_METRIC_SPEC_CLIENT_SUPPORTED;
1198+
#define METRIC_BYTES(cnt) (DIV_ROUND_UP((size_t)metric_bits[cnt - 1] + 1, 64) * 8)
1199+
static int encode_metric_spec(void **p, void *end)
1200+
{
1201+
static const size_t count = ARRAY_SIZE(metric_bits);
1202+
1203+
/* header */
1204+
if (WARN_ON_ONCE(*p + 2 > end))
1205+
return -ERANGE;
1206+
1207+
ceph_encode_8(p, 1); /* version */
1208+
ceph_encode_8(p, 1); /* compat */
1209+
1210+
if (count > 0) {
1211+
size_t i;
1212+
size_t size = METRIC_BYTES(count);
1213+
1214+
if (WARN_ON_ONCE(*p + 4 + 4 + size > end))
1215+
return -ERANGE;
1216+
1217+
/* metric spec info length */
1218+
ceph_encode_32(p, 4 + size);
1219+
1220+
/* metric spec */
1221+
ceph_encode_32(p, size);
1222+
memset(*p, 0, size);
1223+
for (i = 0; i < count; i++)
1224+
((unsigned char *)(*p))[i / 8] |= BIT(metric_bits[i] % 8);
1225+
*p += size;
1226+
} else {
1227+
if (WARN_ON_ONCE(*p + 4 + 4 > end))
1228+
return -ERANGE;
1229+
1230+
/* metric spec info length */
1231+
ceph_encode_32(p, 4);
1232+
/* metric spec */
1233+
ceph_encode_32(p, 0);
1234+
}
1235+
1236+
return 0;
1237+
}
1238+
11971239
/*
11981240
* session message, specialization for CEPH_SESSION_REQUEST_OPEN
11991241
* to include additional client metadata fields.
@@ -1234,6 +1276,13 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
12341276
size = FEATURE_BYTES(count);
12351277
extra_bytes += 4 + size;
12361278

1279+
/* metric spec */
1280+
size = 0;
1281+
count = ARRAY_SIZE(metric_bits);
1282+
if (count > 0)
1283+
size = METRIC_BYTES(count);
1284+
extra_bytes += 2 + 4 + 4 + size;
1285+
12371286
/* Allocate the message */
12381287
msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h) + extra_bytes,
12391288
GFP_NOFS, false);
@@ -1252,9 +1301,9 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
12521301
* Serialize client metadata into waiting buffer space, using
12531302
* the format that userspace expects for map<string, string>
12541303
*
1255-
* ClientSession messages with metadata are v3
1304+
* ClientSession messages with metadata are v4
12561305
*/
1257-
msg->hdr.version = cpu_to_le16(3);
1306+
msg->hdr.version = cpu_to_le16(4);
12581307
msg->hdr.compat_version = cpu_to_le16(1);
12591308

12601309
/* The write pointer, following the session_head structure */
@@ -1283,6 +1332,13 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
12831332
return ERR_PTR(ret);
12841333
}
12851334

1335+
ret = encode_metric_spec(&p, end);
1336+
if (ret) {
1337+
pr_err("encode_metric_spec failed!\n");
1338+
ceph_msg_put(msg);
1339+
return ERR_PTR(ret);
1340+
}
1341+
12861342
msg->front.iov_len = p - msg->front.iov_base;
12871343
msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);
12881344

fs/ceph/metric.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@ enum ceph_metric_type {
1818
CLIENT_METRIC_TYPE_MAX = CLIENT_METRIC_TYPE_DENTRY_LEASE,
1919
};
2020

21+
/*
22+
* This will always have the highest metric bit value
23+
* as the last element of the array.
24+
*/
25+
#define CEPHFS_METRIC_SPEC_CLIENT_SUPPORTED { \
26+
CLIENT_METRIC_TYPE_CAP_INFO, \
27+
CLIENT_METRIC_TYPE_READ_LATENCY, \
28+
CLIENT_METRIC_TYPE_WRITE_LATENCY, \
29+
CLIENT_METRIC_TYPE_METADATA_LATENCY, \
30+
\
31+
CLIENT_METRIC_TYPE_MAX, \
32+
}
33+
2134
/* metric caps header */
2235
struct ceph_metric_cap {
2336
__le32 type; /* ceph metric type */

0 commit comments

Comments
 (0)