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 committed by Chris Goldsworthy
parent 8acc562ba7
commit bf87ba269b
2 changed files with 88 additions and 3 deletions

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _UAPI_MSM_SYSSTATS_H_
#define _UAPI_MSM_SYSSTATS_H_
@ -8,7 +9,7 @@
#include <linux/types.h>
#define SYSSTATS_GENL_NAME "SYSSTATS"
#define SYSSTATS_GENL_VERSION 0x1
#define SYSSTATS_GENL_VERSION 0x2
#define TS_COMM_LEN 32
@ -17,16 +18,21 @@
#define SYSSTATS_TYPE_NULL 2
#define SYSSTATS_TASK_TYPE_FOREACH 3
#define SYSSTATS_MEMINFO_TYPE_STATS 4
#define SYSSTATS_PID_TYPE_STATS 5
#define SYSSTATS_CMD_ATTR_UNSPEC 0
#define SYSSTATS_TASK_CMD_ATTR_PID 1
#define SYSSTATS_TASK_CMD_ATTR_FOREACH 2
#define SYSSTATS_TASK_CMD_ATTR_PIDS_OF_NAME 3
#define SYSSTATS_CMD_UNSPEC 0
#define SYSSTATS_TASK_CMD_GET 1
#define SYSSTATS_TASK_CMD_NEW 2
#define SYSSTATS_MEMINFO_CMD_GET 3
#define SYSSTATS_MEMINFO_CMD_NEW 4
#define SYSSTATS_PIDS_CMD_GET 5
#define SYSSTATS_PIDS_CMD_NEW 6
struct sysstats_task {
__u64 anon_rss; /* KB */
@ -89,4 +95,8 @@ struct sysstats_mem {
__u64 highmem_nr_inactive_file;
};
struct sysstats_pid {
__u64 pid;
};
#endif /* _UAPI_MSM_SYSSTATS_H_ */

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/kernel.h>
@ -28,10 +29,11 @@ struct tgid_iter {
static struct genl_family family;
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] = {
[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,
struct genl_info *info)
@ -40,6 +42,7 @@ static int sysstats_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
switch (ops->cmd) {
case SYSSTATS_TASK_CMD_GET:
case SYSSTATS_PIDS_CMD_GET:
policy = sysstats_cmd_get_policy;
break;
case SYSSTATS_MEMINFO_CMD_GET:
@ -194,6 +197,21 @@ static unsigned long get_system_unreclaimble_info(void)
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)
{
@ -321,6 +339,58 @@ static struct tgid_iter next_tgid(struct pid_namespace *ns, struct tgid_iter ite
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)
{
struct pid_namespace *ns = task_active_pid_ns(current);
@ -549,6 +619,11 @@ static const struct genl_ops sysstats_ops[] = {
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.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 = {