Skip to content

Commit

Permalink
ceph: send client provided metric flags in client metadata
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Xiubo Li authored and Ilya Dryomov committed Aug 3, 2020
1 parent 18f473b commit 3b4168d
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 2 deletions.
60 changes: 58 additions & 2 deletions fs/ceph/mds_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1194,6 +1194,48 @@ static int encode_supported_features(void **p, void *end)
return 0;
}

static const unsigned char metric_bits[] = CEPHFS_METRIC_SPEC_CLIENT_SUPPORTED;
#define METRIC_BYTES(cnt) (DIV_ROUND_UP((size_t)metric_bits[cnt - 1] + 1, 64) * 8)
static int encode_metric_spec(void **p, void *end)
{
static const size_t count = ARRAY_SIZE(metric_bits);

/* header */
if (WARN_ON_ONCE(*p + 2 > end))
return -ERANGE;

ceph_encode_8(p, 1); /* version */
ceph_encode_8(p, 1); /* compat */

if (count > 0) {
size_t i;
size_t size = METRIC_BYTES(count);

if (WARN_ON_ONCE(*p + 4 + 4 + size > end))
return -ERANGE;

/* metric spec info length */
ceph_encode_32(p, 4 + size);

/* metric spec */
ceph_encode_32(p, size);
memset(*p, 0, size);
for (i = 0; i < count; i++)
((unsigned char *)(*p))[i / 8] |= BIT(metric_bits[i] % 8);
*p += size;
} else {
if (WARN_ON_ONCE(*p + 4 + 4 > end))
return -ERANGE;

/* metric spec info length */
ceph_encode_32(p, 4);
/* metric spec */
ceph_encode_32(p, 0);
}

return 0;
}

/*
* session message, specialization for CEPH_SESSION_REQUEST_OPEN
* to include additional client metadata fields.
Expand Down Expand Up @@ -1234,6 +1276,13 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
size = FEATURE_BYTES(count);
extra_bytes += 4 + size;

/* metric spec */
size = 0;
count = ARRAY_SIZE(metric_bits);
if (count > 0)
size = METRIC_BYTES(count);
extra_bytes += 2 + 4 + 4 + size;

/* Allocate the message */
msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h) + extra_bytes,
GFP_NOFS, false);
Expand All @@ -1252,9 +1301,9 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
* Serialize client metadata into waiting buffer space, using
* the format that userspace expects for map<string, string>
*
* ClientSession messages with metadata are v3
* ClientSession messages with metadata are v4
*/
msg->hdr.version = cpu_to_le16(3);
msg->hdr.version = cpu_to_le16(4);
msg->hdr.compat_version = cpu_to_le16(1);

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

ret = encode_metric_spec(&p, end);
if (ret) {
pr_err("encode_metric_spec failed!\n");
ceph_msg_put(msg);
return ERR_PTR(ret);
}

msg->front.iov_len = p - msg->front.iov_base;
msg->hdr.front_len = cpu_to_le32(msg->front.iov_len);

Expand Down
13 changes: 13 additions & 0 deletions fs/ceph/metric.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,19 @@ enum ceph_metric_type {
CLIENT_METRIC_TYPE_MAX = CLIENT_METRIC_TYPE_DENTRY_LEASE,
};

/*
* This will always have the highest metric bit value
* as the last element of the array.
*/
#define CEPHFS_METRIC_SPEC_CLIENT_SUPPORTED { \
CLIENT_METRIC_TYPE_CAP_INFO, \
CLIENT_METRIC_TYPE_READ_LATENCY, \
CLIENT_METRIC_TYPE_WRITE_LATENCY, \
CLIENT_METRIC_TYPE_METADATA_LATENCY, \
\
CLIENT_METRIC_TYPE_MAX, \
}

/* metric caps header */
struct ceph_metric_cap {
__le32 type; /* ceph metric type */
Expand Down

0 comments on commit 3b4168d

Please sign in to comment.