msm-sysstats: given process name return the pid's

Add support to give the range of pid's that corresponds to a given
running process.

Change-Id: I93d258edd40373c233177bfa9c299434e13cc718
Signed-off-by: Charan Teja Reddy <quic_charante@quicinc.com>
This commit is contained in:
Charan Teja Reddy
2022-02-23 18:58:52 +05:30
parent 8d3eace585
commit c11c03e18c
2 changed files with 86 additions and 3 deletions

View File

@@ -8,7 +8,7 @@
#include <linux/types.h> #include <linux/types.h>
#define SYSSTATS_GENL_NAME "SYSSTATS" #define SYSSTATS_GENL_NAME "SYSSTATS"
#define SYSSTATS_GENL_VERSION 0x1 #define SYSSTATS_GENL_VERSION 0x2
#define TS_COMM_LEN 32 #define TS_COMM_LEN 32
@@ -17,16 +17,21 @@
#define SYSSTATS_TYPE_NULL 2 #define SYSSTATS_TYPE_NULL 2
#define SYSSTATS_TASK_TYPE_FOREACH 3 #define SYSSTATS_TASK_TYPE_FOREACH 3
#define SYSSTATS_MEMINFO_TYPE_STATS 4 #define SYSSTATS_MEMINFO_TYPE_STATS 4
#define SYSSTATS_PID_TYPE_STATS 5
#define SYSSTATS_CMD_ATTR_UNSPEC 0 #define SYSSTATS_CMD_ATTR_UNSPEC 0
#define SYSSTATS_TASK_CMD_ATTR_PID 1 #define SYSSTATS_TASK_CMD_ATTR_PID 1
#define SYSSTATS_TASK_CMD_ATTR_FOREACH 2 #define SYSSTATS_TASK_CMD_ATTR_FOREACH 2
#define SYSSTATS_TASK_CMD_ATTR_PIDS_OF_NAME 3
#define SYSSTATS_CMD_UNSPEC 0 #define SYSSTATS_CMD_UNSPEC 0
#define SYSSTATS_TASK_CMD_GET 1 #define SYSSTATS_TASK_CMD_GET 1
#define SYSSTATS_TASK_CMD_NEW 2 #define SYSSTATS_TASK_CMD_NEW 2
#define SYSSTATS_MEMINFO_CMD_GET 3 #define SYSSTATS_MEMINFO_CMD_GET 3
#define SYSSTATS_MEMINFO_CMD_NEW 4 #define SYSSTATS_MEMINFO_CMD_NEW 4
#define SYSSTATS_PIDS_CMD_GET 5
#define SYSSTATS_PIDS_CMD_NEW 6
struct sysstats_task { struct sysstats_task {
__u64 anon_rss; /* KB */ __u64 anon_rss; /* KB */
@@ -89,4 +94,8 @@ struct sysstats_mem {
__u64 highmem_nr_inactive_file; __u64 highmem_nr_inactive_file;
}; };
struct sysstats_pid {
__u64 pid;
};
#endif /* _UAPI_MSM_SYSSTATS_H_ */ #endif /* _UAPI_MSM_SYSSTATS_H_ */

View File

@@ -28,10 +28,11 @@ struct tgid_iter {
static struct genl_family family; static struct genl_family family;
static DEFINE_PER_CPU(__u32, sysstats_seqnum); static DEFINE_PER_CPU(__u32, sysstats_seqnum);
#define SYSSTATS_CMD_ATTR_MAX 2 #define SYSSTATS_CMD_ATTR_MAX 3
static const struct nla_policy sysstats_cmd_get_policy[SYSSTATS_CMD_ATTR_MAX + 1] = { static const struct nla_policy sysstats_cmd_get_policy[SYSSTATS_CMD_ATTR_MAX + 1] = {
[SYSSTATS_TASK_CMD_ATTR_PID] = { .type = NLA_U32 }, [SYSSTATS_TASK_CMD_ATTR_PID] = { .type = NLA_U32 },
[SYSSTATS_TASK_CMD_ATTR_FOREACH] = { .type = NLA_U32 },}; [SYSSTATS_TASK_CMD_ATTR_FOREACH] = { .type = NLA_U32 },
[SYSSTATS_TASK_CMD_ATTR_PIDS_OF_NAME] = { .type = NLA_NUL_STRING}};
static int sysstats_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, static int sysstats_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
struct genl_info *info) struct genl_info *info)
@@ -40,6 +41,7 @@ static int sysstats_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
switch (ops->cmd) { switch (ops->cmd) {
case SYSSTATS_TASK_CMD_GET: case SYSSTATS_TASK_CMD_GET:
case SYSSTATS_PIDS_CMD_GET:
policy = sysstats_cmd_get_policy; policy = sysstats_cmd_get_policy;
break; break;
case SYSSTATS_MEMINFO_CMD_GET: case SYSSTATS_MEMINFO_CMD_GET:
@@ -194,6 +196,21 @@ static unsigned long get_system_unreclaimble_info(void)
return size; return size;
} }
static char *nla_strdup_cust(const struct nlattr *nla, gfp_t flags)
{
size_t srclen = nla_len(nla);
char *src = nla_data(nla), *dst;
if (srclen > 0 && src[srclen - 1] == '\0')
srclen--;
dst = kmalloc(srclen + 1, flags);
if (dst != NULL) {
memcpy(dst, src, srclen);
dst[srclen] = '\0';
}
return dst;
}
static int sysstats_task_cmd_attr_pid(struct genl_info *info) static int sysstats_task_cmd_attr_pid(struct genl_info *info)
{ {
@@ -321,6 +338,58 @@ retry:
return iter; return iter;
} }
static int sysstats_all_pids_of_name(struct sk_buff *skb, struct netlink_callback *cb)
{
struct pid_namespace *ns = task_active_pid_ns(current);
struct tgid_iter iter;
void *reply;
struct nlattr *attr;
struct nlattr *nla;
struct sysstats_pid *stats;
char *comm;
nla = nla_find(nlmsg_attrdata(cb->nlh, GENL_HDRLEN),
nlmsg_attrlen(cb->nlh, GENL_HDRLEN),
SYSSTATS_TASK_CMD_ATTR_PIDS_OF_NAME);
if (!nla)
goto out;
comm = nla_strdup_cust(nla, GFP_KERNEL);
iter.tgid = cb->args[0];
iter.task = NULL;
for (iter = next_tgid(ns, iter); iter.task;
iter.tgid += 1, iter = next_tgid(ns, iter)) {
if (strcmp(iter.task->comm, comm))
continue;
reply = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, &family, 0, SYSSTATS_PIDS_CMD_GET);
if (reply == NULL) {
put_task_struct(iter.task);
break;
}
attr = nla_reserve(skb, SYSSTATS_PID_TYPE_STATS,
sizeof(struct sysstats_pid));
if (!attr) {
put_task_struct(iter.task);
genlmsg_cancel(skb, reply);
break;
}
stats = nla_data(attr);
memset(stats, 0, sizeof(struct sysstats_pid));
rcu_read_lock();
stats->pid = task_pid_nr_ns(iter.task,
task_active_pid_ns(current));
rcu_read_unlock();
genlmsg_end(skb, reply);
}
cb->args[0] = iter.tgid;
kfree(comm);
out:
return skb->len;
}
static int sysstats_task_foreach(struct sk_buff *skb, struct netlink_callback *cb) static int sysstats_task_foreach(struct sk_buff *skb, struct netlink_callback *cb)
{ {
struct pid_namespace *ns = task_active_pid_ns(current); struct pid_namespace *ns = task_active_pid_ns(current);
@@ -555,6 +624,11 @@ static const struct genl_ops sysstats_ops[] = {
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = sysstats_meminfo_user_cmd, .doit = sysstats_meminfo_user_cmd,
}, },
{
.cmd = SYSSTATS_PIDS_CMD_GET,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.dumpit = sysstats_all_pids_of_name,
}
}; };
static struct genl_family family __ro_after_init = { static struct genl_family family __ro_after_init = {