All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chuck Lever <chuck.lever@oracle.com>
To: Lorenzo Bianconi <lorenzo@kernel.org>
Cc: linux-nfs@vger.kernel.org, lorenzo.bianconi@redhat.com,
	neilb@suse.de, netdev@vger.kernel.org, jlayton@kernel.org,
	kuba@kernel.org
Subject: Re: [PATCH v4 1/3] NFSD: convert write_threads to netlink command
Date: Sat, 11 Nov 2023 13:57:34 -0500	[thread overview]
Message-ID: <ZU/OntVC2qEwrsQd@tissot.1015granger.net> (raw)
In-Reply-To: <ac01a0f3972dd8175238e27a69db0acf0fed89db.1699095665.git.lorenzo@kernel.org>

On Sat, Nov 04, 2023 at 12:13:45PM +0100, Lorenzo Bianconi wrote:
> Introduce write_threads netlink command similar to the ones available
> through the procfs.
> 
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  Documentation/netlink/specs/nfsd.yaml | 23 +++++++
>  fs/nfsd/netlink.c                     | 17 +++++
>  fs/nfsd/netlink.h                     |  2 +
>  fs/nfsd/nfsctl.c                      | 58 +++++++++++++++++
>  include/uapi/linux/nfsd_netlink.h     |  9 +++
>  tools/net/ynl/generated/nfsd-user.c   | 92 +++++++++++++++++++++++++++
>  tools/net/ynl/generated/nfsd-user.h   | 47 ++++++++++++++
>  7 files changed, 248 insertions(+)

Hi Lorenzo -

This doesn't apply to my private nfsd-next branch. I don't believe
that's your fault... We've got some things in flight here that
conflict with what is in net-next.

Jakub tells me there is some ynl churn coming in v6.7-rc1 that
might resolve the conflicts.

I plan to rebase my private nfsd-next on v6.7-rc1 and push the first
set of patches on Monday or Tuesday. Please rebase this series on
top of that, regen the ynl code, and then send a v5. I will then
apply that to nfsd-next for more testing and review.


> diff --git a/Documentation/netlink/specs/nfsd.yaml b/Documentation/netlink/specs/nfsd.yaml
> index 05acc73e2e33..c92e1425d316 100644
> --- a/Documentation/netlink/specs/nfsd.yaml
> +++ b/Documentation/netlink/specs/nfsd.yaml
> @@ -62,6 +62,12 @@ attribute-sets:
>          name: compound-ops
>          type: u32
>          multi-attr: true
> +  -
> +    name: server-worker
> +    attributes:
> +      -
> +        name: threads
> +        type: u32
>  
>  operations:
>    list:
> @@ -87,3 +93,20 @@ operations:
>              - sport
>              - dport
>              - compound-ops
> +    -
> +      name: threads-set
> +      doc: set the number of running threads
> +      attribute-set: server-worker
> +      flags: [ admin-perm ]
> +      do:
> +        request:
> +          attributes:
> +            - threads
> +    -
> +      name: threads-get
> +      doc: get the number of running threads
> +      attribute-set: server-worker
> +      do:
> +        reply:
> +          attributes:
> +            - threads
> diff --git a/fs/nfsd/netlink.c b/fs/nfsd/netlink.c
> index 0e1d635ec5f9..1a59a8e6c7e2 100644
> --- a/fs/nfsd/netlink.c
> +++ b/fs/nfsd/netlink.c
> @@ -10,6 +10,11 @@
>  
>  #include <uapi/linux/nfsd_netlink.h>
>  
> +/* NFSD_CMD_THREADS_SET - do */
> +static const struct nla_policy nfsd_threads_set_nl_policy[NFSD_A_SERVER_WORKER_THREADS + 1] = {
> +	[NFSD_A_SERVER_WORKER_THREADS] = { .type = NLA_U32, },
> +};
> +
>  /* Ops table for nfsd */
>  static const struct genl_split_ops nfsd_nl_ops[] = {
>  	{
> @@ -19,6 +24,18 @@ static const struct genl_split_ops nfsd_nl_ops[] = {
>  		.done	= nfsd_nl_rpc_status_get_done,
>  		.flags	= GENL_CMD_CAP_DUMP,
>  	},
> +	{
> +		.cmd		= NFSD_CMD_THREADS_SET,
> +		.doit		= nfsd_nl_threads_set_doit,
> +		.policy		= nfsd_threads_set_nl_policy,
> +		.maxattr	= NFSD_A_SERVER_WORKER_THREADS,
> +		.flags		= GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
> +	},
> +	{
> +		.cmd	= NFSD_CMD_THREADS_GET,
> +		.doit	= nfsd_nl_threads_get_doit,
> +		.flags	= GENL_CMD_CAP_DO,
> +	},
>  };
>  
>  struct genl_family nfsd_nl_family __ro_after_init = {
> diff --git a/fs/nfsd/netlink.h b/fs/nfsd/netlink.h
> index d83dd6bdee92..4137fac477e4 100644
> --- a/fs/nfsd/netlink.h
> +++ b/fs/nfsd/netlink.h
> @@ -16,6 +16,8 @@ int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb);
>  
>  int nfsd_nl_rpc_status_get_dumpit(struct sk_buff *skb,
>  				  struct netlink_callback *cb);
> +int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info);
> +int nfsd_nl_threads_get_doit(struct sk_buff *skb, struct genl_info *info);
>  
>  extern struct genl_family nfsd_nl_family;
>  
> diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
> index 739ed5bf71cd..0d0394887506 100644
> --- a/fs/nfsd/nfsctl.c
> +++ b/fs/nfsd/nfsctl.c
> @@ -1693,6 +1693,64 @@ int nfsd_nl_rpc_status_get_done(struct netlink_callback *cb)
>  	return 0;
>  }
>  
> +/**
> + * nfsd_nl_threads_set_doit - set the number of running threads
> + * @skb: reply buffer
> + * @info: netlink metadata and command arguments
> + *
> + * Return 0 on success or a negative errno.
> + */
> +int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info)
> +{
> +	u32 nthreads;
> +	int ret;
> +
> +	if (GENL_REQ_ATTR_CHECK(info, NFSD_A_SERVER_WORKER_THREADS))
> +		return -EINVAL;
> +
> +	nthreads = nla_get_u32(info->attrs[NFSD_A_SERVER_WORKER_THREADS]);
> +	ret = nfsd_svc(nthreads, genl_info_net(info), get_current_cred());
> +
> +	return ret == nthreads ? 0 : ret;
> +}
> +
> +/**
> + * nfsd_nl_threads_get_doit - get the number of running threads
> + * @skb: reply buffer
> + * @info: netlink metadata and command arguments
> + *
> + * Return 0 on success or a negative errno.
> + */
> +int nfsd_nl_threads_get_doit(struct sk_buff *skb, struct genl_info *info)
> +{
> +	void *hdr;
> +	int err;
> +
> +	skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
> +	if (!skb)
> +		return -ENOMEM;
> +
> +	hdr = genlmsg_iput(skb, info);
> +	if (!hdr) {
> +		err = -EMSGSIZE;
> +		goto err_free_msg;
> +	}
> +
> +	if (nla_put_u32(skb, NFSD_A_SERVER_WORKER_THREADS,
> +			nfsd_nrthreads(genl_info_net(info)))) {
> +		err = -EINVAL;
> +		goto err_free_msg;
> +	}
> +
> +	genlmsg_end(skb, hdr);
> +
> +	return genlmsg_reply(skb, info);
> +
> +err_free_msg:
> +	nlmsg_free(skb);
> +	return err;
> +}
> +
>  /**
>   * nfsd_net_init - Prepare the nfsd_net portion of a new net namespace
>   * @net: a freshly-created network namespace
> diff --git a/include/uapi/linux/nfsd_netlink.h b/include/uapi/linux/nfsd_netlink.h
> index c8ae72466ee6..99f7855852a1 100644
> --- a/include/uapi/linux/nfsd_netlink.h
> +++ b/include/uapi/linux/nfsd_netlink.h
> @@ -29,8 +29,17 @@ enum {
>  	NFSD_A_RPC_STATUS_MAX = (__NFSD_A_RPC_STATUS_MAX - 1)
>  };
>  
> +enum {
> +	NFSD_A_SERVER_WORKER_THREADS = 1,
> +
> +	__NFSD_A_SERVER_WORKER_MAX,
> +	NFSD_A_SERVER_WORKER_MAX = (__NFSD_A_SERVER_WORKER_MAX - 1)
> +};
> +
>  enum {
>  	NFSD_CMD_RPC_STATUS_GET = 1,
> +	NFSD_CMD_THREADS_SET,
> +	NFSD_CMD_THREADS_GET,
>  
>  	__NFSD_CMD_MAX,
>  	NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1)
> diff --git a/tools/net/ynl/generated/nfsd-user.c b/tools/net/ynl/generated/nfsd-user.c
> index fec6828680ce..342a00b0474a 100644
> --- a/tools/net/ynl/generated/nfsd-user.c
> +++ b/tools/net/ynl/generated/nfsd-user.c
> @@ -15,6 +15,8 @@
>  /* Enums */
>  static const char * const nfsd_op_strmap[] = {
>  	[NFSD_CMD_RPC_STATUS_GET] = "rpc-status-get",
> +	[NFSD_CMD_THREADS_SET] = "threads-set",
> +	[NFSD_CMD_THREADS_GET] = "threads-get",
>  };
>  
>  const char *nfsd_op_str(int op)
> @@ -47,6 +49,15 @@ struct ynl_policy_nest nfsd_rpc_status_nest = {
>  	.table = nfsd_rpc_status_policy,
>  };
>  
> +struct ynl_policy_attr nfsd_server_worker_policy[NFSD_A_SERVER_WORKER_MAX + 1] = {
> +	[NFSD_A_SERVER_WORKER_THREADS] = { .name = "threads", .type = YNL_PT_U32, },
> +};
> +
> +struct ynl_policy_nest nfsd_server_worker_nest = {
> +	.max_attr = NFSD_A_SERVER_WORKER_MAX,
> +	.table = nfsd_server_worker_policy,
> +};
> +
>  /* Common nested types */
>  /* ============== NFSD_CMD_RPC_STATUS_GET ============== */
>  /* NFSD_CMD_RPC_STATUS_GET - dump */
> @@ -90,6 +101,87 @@ struct nfsd_rpc_status_get_list *nfsd_rpc_status_get_dump(struct ynl_sock *ys)
>  	return NULL;
>  }
>  
> +/* ============== NFSD_CMD_THREADS_SET ============== */
> +/* NFSD_CMD_THREADS_SET - do */
> +void nfsd_threads_set_req_free(struct nfsd_threads_set_req *req)
> +{
> +	free(req);
> +}
> +
> +int nfsd_threads_set(struct ynl_sock *ys, struct nfsd_threads_set_req *req)
> +{
> +	struct nlmsghdr *nlh;
> +	int err;
> +
> +	nlh = ynl_gemsg_start_req(ys, ys->family_id, NFSD_CMD_THREADS_SET, 1);
> +	ys->req_policy = &nfsd_server_worker_nest;
> +
> +	if (req->_present.threads)
> +		mnl_attr_put_u32(nlh, NFSD_A_SERVER_WORKER_THREADS, req->threads);
> +
> +	err = ynl_exec(ys, nlh, NULL);
> +	if (err < 0)
> +		return -1;
> +
> +	return 0;
> +}
> +
> +/* ============== NFSD_CMD_THREADS_GET ============== */
> +/* NFSD_CMD_THREADS_GET - do */
> +void nfsd_threads_get_rsp_free(struct nfsd_threads_get_rsp *rsp)
> +{
> +	free(rsp);
> +}
> +
> +int nfsd_threads_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
> +{
> +	struct ynl_parse_arg *yarg = data;
> +	struct nfsd_threads_get_rsp *dst;
> +	const struct nlattr *attr;
> +
> +	dst = yarg->data;
> +
> +	mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
> +		unsigned int type = mnl_attr_get_type(attr);
> +
> +		if (type == NFSD_A_SERVER_WORKER_THREADS) {
> +			if (ynl_attr_validate(yarg, attr))
> +				return MNL_CB_ERROR;
> +			dst->_present.threads = 1;
> +			dst->threads = mnl_attr_get_u32(attr);
> +		}
> +	}
> +
> +	return MNL_CB_OK;
> +}
> +
> +struct nfsd_threads_get_rsp *nfsd_threads_get(struct ynl_sock *ys)
> +{
> +	struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
> +	struct nfsd_threads_get_rsp *rsp;
> +	struct nlmsghdr *nlh;
> +	int err;
> +
> +	nlh = ynl_gemsg_start_req(ys, ys->family_id, NFSD_CMD_THREADS_GET, 1);
> +	ys->req_policy = &nfsd_server_worker_nest;
> +	yrs.yarg.rsp_policy = &nfsd_server_worker_nest;
> +
> +	rsp = calloc(1, sizeof(*rsp));
> +	yrs.yarg.data = rsp;
> +	yrs.cb = nfsd_threads_get_rsp_parse;
> +	yrs.rsp_cmd = NFSD_CMD_THREADS_GET;
> +
> +	err = ynl_exec(ys, nlh, &yrs);
> +	if (err < 0)
> +		goto err_free;
> +
> +	return rsp;
> +
> +err_free:
> +	nfsd_threads_get_rsp_free(rsp);
> +	return NULL;
> +}
> +
>  const struct ynl_family ynl_nfsd_family =  {
>  	.name		= "nfsd",
>  };
> diff --git a/tools/net/ynl/generated/nfsd-user.h b/tools/net/ynl/generated/nfsd-user.h
> index b6b69501031a..4c11119217f1 100644
> --- a/tools/net/ynl/generated/nfsd-user.h
> +++ b/tools/net/ynl/generated/nfsd-user.h
> @@ -30,4 +30,51 @@ void nfsd_rpc_status_get_list_free(struct nfsd_rpc_status_get_list *rsp);
>  
>  struct nfsd_rpc_status_get_list *nfsd_rpc_status_get_dump(struct ynl_sock *ys);
>  
> +/* ============== NFSD_CMD_THREADS_SET ============== */
> +/* NFSD_CMD_THREADS_SET - do */
> +struct nfsd_threads_set_req {
> +	struct {
> +		__u32 threads:1;
> +	} _present;
> +
> +	__u32 threads;
> +};
> +
> +static inline struct nfsd_threads_set_req *nfsd_threads_set_req_alloc(void)
> +{
> +	return calloc(1, sizeof(struct nfsd_threads_set_req));
> +}
> +void nfsd_threads_set_req_free(struct nfsd_threads_set_req *req);
> +
> +static inline void
> +nfsd_threads_set_req_set_threads(struct nfsd_threads_set_req *req,
> +				 __u32 threads)
> +{
> +	req->_present.threads = 1;
> +	req->threads = threads;
> +}
> +
> +/*
> + * set the number of running threads
> + */
> +int nfsd_threads_set(struct ynl_sock *ys, struct nfsd_threads_set_req *req);
> +
> +/* ============== NFSD_CMD_THREADS_GET ============== */
> +/* NFSD_CMD_THREADS_GET - do */
> +
> +struct nfsd_threads_get_rsp {
> +	struct {
> +		__u32 threads:1;
> +	} _present;
> +
> +	__u32 threads;
> +};
> +
> +void nfsd_threads_get_rsp_free(struct nfsd_threads_get_rsp *rsp);
> +
> +/*
> + * get the number of running threads
> + */
> +struct nfsd_threads_get_rsp *nfsd_threads_get(struct ynl_sock *ys);
> +
>  #endif /* _LINUX_NFSD_GEN_H */
> -- 
> 2.41.0
> 

-- 
Chuck Lever

  reply	other threads:[~2023-11-11 18:57 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-04 11:13 [PATCH v4 0/3] convert write_threads, write_version and write_ports to netlink commands Lorenzo Bianconi
2023-11-04 11:13 ` [PATCH v4 1/3] NFSD: convert write_threads to netlink command Lorenzo Bianconi
2023-11-11 18:57   ` Chuck Lever [this message]
2023-11-12  9:43     ` Lorenzo Bianconi
2023-11-04 11:13 ` [PATCH v4 2/3] NFSD: convert write_version " Lorenzo Bianconi
2023-11-04 16:01   ` kernel test robot
2023-11-04 11:13 ` [PATCH v4 3/3] NFSD: convert write_ports " Lorenzo Bianconi
2023-11-04 20:56   ` kernel test robot
2023-11-11 19:52 ` [PATCH v4 0/3] convert write_threads, write_version and write_ports to netlink commands Jeff Layton
2023-11-12 10:02   ` Lorenzo Bianconi
2023-11-12 11:09     ` Jeff Layton
2023-11-12 15:33       ` Chuck Lever III
2023-11-12 20:22       ` NeilBrown
2023-11-27 12:35         ` Jeff Layton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZU/OntVC2qEwrsQd@tissot.1015granger.net \
    --to=chuck.lever@oracle.com \
    --cc=jlayton@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=lorenzo.bianconi@redhat.com \
    --cc=lorenzo@kernel.org \
    --cc=neilb@suse.de \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.