linux-clk.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jiri Pirko <jiri@resnulli.us>
To: Vadim Fedorenko <vadfed@meta.com>
Cc: Jakub Kicinski <kuba@kernel.org>,
	Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>,
	Jonathan Lemon <jonathan.lemon@gmail.com>,
	Paolo Abeni <pabeni@redhat.com>,
	Vadim Fedorenko <vadim.fedorenko@linux.dev>,
	poros@redhat.com, mschmidt@redhat.com, netdev@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org,
	Milena Olech <milena.olech@intel.com>,
	Michal Michalik <michal.michalik@intel.com>
Subject: Re: [PATCH RFC v6 2/6] dpll: Add DPLL framework base functions
Date: Thu, 23 Mar 2023 12:18:12 +0100	[thread overview]
Message-ID: <ZBw1dID2U9D7wMyy@nanopsycho> (raw)
In-Reply-To: <20230312022807.278528-3-vadfed@meta.com>

Sun, Mar 12, 2023 at 03:28:03AM CET, vadfed@meta.com wrote:

[...]


>+/**
>+ * dpll_xa_ref_pin_del - remove reference of a pin from xarray
>+ * @xa_pins: dpll_pin_ref xarray holding pins
>+ * @pin: pointer to a pin
>+ *
>+ * Decrement refcount of existing pin reference on given xarray.
>+ * If all references are dropped, delete the reference and free its memory.
>+ *

Hmm, came to think about this, why do you do func docs even for static
function? It is customary to do that for exported function. For static
ones, not really needed.


>+ * Return:
>+ * * 0 on success
>+ * * -EINVAL if reference to a pin was not found
>+ */
>+static int dpll_xa_ref_pin_del(struct xarray *xa_pins, struct dpll_pin *pin)

Have this to return void, you don't check the return value anywhere.


>+{
>+	struct dpll_pin_ref *ref;
>+	unsigned long i;
>+
>+	xa_for_each(xa_pins, i, ref) {
>+		if (ref->pin == pin) {
>+			if (refcount_dec_and_test(&ref->refcount)) {
>+				xa_erase(xa_pins, i);
>+				kfree(ref);
>+			}
>+			return 0;
>+		}
>+	}
>+
>+	return -EINVAL;
>+}

[...]


>+/**
>+ * dpll_xa_ref_dpll_find - find dpll reference on xarray
>+ * @xa_dplls: dpll_pin_ref xarray holding dplls
>+ * @dpll: pointer to a dpll
>+ *
>+ * Search for dpll-pin ops reference struct of a given dpll on given xarray.
>+ *
>+ * Return:
>+ * * pin reference struct pointer on success
>+ * * NULL - reference to a pin was not found
>+ */
>+struct dpll_pin_ref *
>+dpll_xa_ref_dpll_find(struct xarray *xa_refs, const struct dpll_device *dpll)

Every caller of this function does fill the first arg by:
&pin->dpll_refs
Could you please change it to "struct dpll_pin *pin" and get the xarray
pointer in this function?

The same applies to other functions passing xarray pointer, like:
dpll_xa_ref_dpll_add
dpll_xa_ref_dpll_del
dpll_xa_ref_pin_find

The point is, always better and easier to read to pass
"struct dpll_device *" and "struct dpll_pin *" as function args.
Passing "struct xarray *" makes the reader uncertain about what
is going on.



>+{
>+	struct dpll_pin_ref *ref;
>+	unsigned long i;
>+
>+	xa_for_each(xa_refs, i, ref) {
>+		if (ref->dpll == dpll)
>+			return ref;
>+	}
>+
>+	return NULL;
>+}
>+
>+

[...]


>+/**
>+ * dpll_device_register - register the dpll device in the subsystem
>+ * @dpll: pointer to a dpll
>+ * @type: type of a dpll
>+ * @ops: ops for a dpll device
>+ * @priv: pointer to private information of owner
>+ * @owner: pointer to owner device
>+ *
>+ * Make dpll device available for user space.
>+ *
>+ * Return:
>+ * * 0 on success
>+ * * -EINVAL on failure

You return more than that. Do you really need to list the error
possiblities in the func docs?


>+ */
>+int dpll_device_register(struct dpll_device *dpll, enum dpll_type type,
>+			 struct dpll_device_ops *ops, void *priv,
>+			 struct device *owner)

[...]


>+static int
>+__dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin,
>+		    struct dpll_pin_ops *ops, void *priv,
>+		    const char *rclk_device_name)
>+{
>+	int ret;
>+
>+	if (rclk_device_name && !pin->rclk_dev_name) {
>+		pin->rclk_dev_name = kstrdup(rclk_device_name, GFP_KERNEL);
>+		if (!pin->rclk_dev_name)
>+			return -ENOMEM;
>+	}

Somewhere here, please add a check:
dpll->module == pin->module dpll->clock_id && pin->clock_id
For sanity sake.


>+	ret = dpll_xa_ref_pin_add(&dpll->pin_refs, pin, ops, priv);
>+	if (ret)
>+		goto rclk_free;
>+	ret = dpll_xa_ref_dpll_add(&pin->dpll_refs, dpll, ops, priv);
>+	if (ret)
>+		goto ref_pin_del;
>+	else
>+		dpll_pin_notify(dpll, pin, DPLL_A_PIN_IDX);

Pointless else.


>+
>+	return ret;
>+
>+ref_pin_del:
>+	dpll_xa_ref_pin_del(&dpll->pin_refs, pin);
>+rclk_free:
>+	kfree(pin->rclk_dev_name);
>+	return ret;
>+}

[...]


>+int
>+dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin,
>+			 struct dpll_pin_ops *ops, void *priv,
>+			 struct device *rclk_device)
>+{
>+	struct dpll_pin_ref *ref;
>+	unsigned long i, stop;
>+	int ret;
>+
>+	if (WARN_ON(!pin || !parent))
>+		return -EINVAL;
>+	if (WARN_ON(parent->prop.type != DPLL_PIN_TYPE_MUX))
>+		return -EPERM;
>+	mutex_lock(&dpll_pin_xa_lock);
>+	ret = dpll_xa_ref_pin_add(&pin->parent_refs, parent, ops, priv);
>+	if (ret)
>+		goto unlock;
>+	refcount_inc(&pin->refcount);
>+	xa_for_each(&parent->dpll_refs, i, ref) {
>+		mutex_lock(&dpll_device_xa_lock);
>+		ret = __dpll_pin_register(ref->dpll, pin, ops, priv,

Why exactly do you need to register the pin over to the dpll of a
parent? Isn't it enough to have the pin registered on a parent?
I mean, there is no direct connection between pin and dpll, the parent
is in the middle. So prio setup, and other things does not make sense to
configure on this child pin, isn't it?

Btw, what is stopping the driver from:
dpll register
pin1 register on dpll
pin2 register on pin1
pin1 unregister
?
The you would have pin2 registered to dpll incorrectly.


>+					  rclk_device ?
>+					  dev_name(rclk_device) : NULL);
>+		mutex_unlock(&dpll_device_xa_lock);
>+		if (ret) {
>+			stop = i;
>+			goto dpll_unregister;
>+		}
>+		dpll_pin_parent_notify(ref->dpll, pin, parent, DPLL_A_PIN_IDX);
>+	}
>+	mutex_unlock(&dpll_pin_xa_lock);
>+
>+	return ret;
>+
>+dpll_unregister:
>+	xa_for_each(&parent->dpll_refs, i, ref) {
>+		if (i < stop) {
>+			mutex_lock(&dpll_device_xa_lock);
>+			__dpll_pin_unregister(ref->dpll, pin);
>+			mutex_unlock(&dpll_device_xa_lock);
>+		}
>+	}
>+	refcount_dec(&pin->refcount);
>+	dpll_xa_ref_pin_del(&pin->parent_refs, parent);
>+unlock:
>+	mutex_unlock(&dpll_pin_xa_lock);
>+	return ret;
>+}

[...]


>+static int
>+dpll_pin_on_pin_state_set(struct dpll_device *dpll, struct dpll_pin *pin,
>+			  u32 parent_idx, enum dpll_pin_state state,
>+			  struct netlink_ext_ack *extack)
>+{
>+	struct dpll_pin_ref *ref;
>+	struct dpll_pin *parent;
>+
>+	if (!(DPLL_PIN_CAPS_STATE_CAN_CHANGE & pin->prop.capabilities))

Hmm, why is this capabilities are any good for internal purposes? I
understand the need to expose it to the user, but internally in kernel,
if the driver implements some _set() op, it is good enough indication of
a support of a certain setter. You can check if the relevant _set()
is not null and expose the appropriate capability to the user.



>+		return -EOPNOTSUPP;
>+	parent = dpll_pin_get_by_idx(dpll, parent_idx);

I don't follow. Why do you need dpll pointer to get the parent pin?
The same handle as pin should be used, you have clock_id and driver name
(in next patchsets implementation) that should be enough.
Pin is a separate entity, attached 0:N dplls.

Please remove dpll pointer from here. Also, please remove
dpll->pins_ref, as you are using this array only for this lookup (here
and in dpll_pin_pre_doit())


>+	if (!parent)
>+		return -EINVAL;
>+	ref = dpll_xa_ref_pin_find(&pin->parent_refs, parent);
>+	if (!ref)
>+		return -EINVAL;
>+	if (!ref->ops || !ref->ops->state_on_pin_set)
>+		return -EOPNOTSUPP;
>+	if (ref->ops->state_on_pin_set(pin, parent, state, extack))
>+		return -EFAULT;
>+	dpll_pin_parent_notify(dpll, pin, parent, DPLL_A_PIN_STATE);
>+
>+	return 0;
>+}
>+
>+static int
>+dpll_pin_state_set(struct dpll_device *dpll, struct dpll_pin *pin,
>+		   enum dpll_pin_state state,
>+		   struct netlink_ext_ack *extack)
>+{
>+	struct dpll_pin_ref *ref;
>+
>+	if (!(DPLL_PIN_CAPS_STATE_CAN_CHANGE & pin->prop.capabilities))
>+		return -EOPNOTSUPP;
>+	ref = dpll_xa_ref_dpll_find(&pin->dpll_refs, dpll);
>+	if (!ref)
>+		return -EFAULT;
>+	if (!ref->ops || !ref->ops->state_on_dpll_set)
>+		return -EOPNOTSUPP;
>+	if (ref->ops->state_on_dpll_set(pin, ref->dpll, state, extack))
>+		return -EINVAL;
>+	dpll_pin_notify(ref->dpll, pin, DPLL_A_PIN_STATE);
>+
>+	return 0;
>+}

[...]


>+static int
>+dpll_set_from_nlattr(struct dpll_device *dpll, struct genl_info *info)
>+{
>+	struct nlattr *attr;
>+	enum dpll_mode mode;
>+	int rem, ret = 0;
>+
>+	nla_for_each_attr(attr, genlmsg_data(info->genlhdr),
>+			  genlmsg_len(info->genlhdr), rem) {
>+		switch (nla_type(attr)) {
>+		case DPLL_A_MODE:
>+			mode = nla_get_u8(attr);
>+
>+			if (!dpll->ops || !dpll->ops->mode_set)

Remove the pointless check of ops. This cannot happen (checked in
dpll_device_register())


>+				return -EOPNOTSUPP;
>+			ret = dpll->ops->mode_set(dpll, mode, info->extack);
>+			if (ret)
>+				return ret;
>+			break;
>+		default:
>+			break;
>+		}
>+	}
>+
>+	return ret;
>+}
>+

[...]

  parent reply	other threads:[~2023-03-23 11:18 UTC|newest]

Thread overview: 103+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-12  2:28 [PATCH RFC v6 0/6] Create common DPLL/clock configuration API Vadim Fedorenko
2023-03-12  2:28 ` [PATCH RFC v6 1/6] dpll: spec: Add Netlink spec in YAML Vadim Fedorenko
2023-03-14 14:44   ` Jiri Pirko
2023-03-16 13:15     ` Kubalewski, Arkadiusz
2023-03-16 13:45       ` Jiri Pirko
2023-03-16 15:19         ` Jiri Pirko
2023-03-17  0:53           ` Kubalewski, Arkadiusz
2023-03-17 10:07             ` Jiri Pirko
2023-03-17  0:52         ` Kubalewski, Arkadiusz
2023-03-17 10:05           ` Jiri Pirko
2023-03-17 14:29             ` Jiri Pirko
2023-03-17 15:14             ` Kubalewski, Arkadiusz
2023-03-17 16:20               ` Jiri Pirko
2023-03-17 18:22                 ` Kubalewski, Arkadiusz
2023-03-20  8:10                   ` Jiri Pirko
2023-03-21  4:05       ` Jakub Kicinski
2023-03-21  4:13         ` Jakub Kicinski
2023-03-21  4:20           ` Jakub Kicinski
2023-03-17 16:23   ` Jiri Pirko
2023-03-21  4:00     ` Jakub Kicinski
2023-03-17 16:53   ` Jiri Pirko
2023-03-17 18:50     ` Kubalewski, Arkadiusz
2023-03-12  2:28 ` [PATCH RFC v6 2/6] dpll: Add DPLL framework base functions Vadim Fedorenko
2023-03-13 16:21   ` Jiri Pirko
2023-03-13 22:59     ` Vadim Fedorenko
2023-03-14  9:21       ` Jiri Pirko
2023-03-14 17:50         ` Kubalewski, Arkadiusz
2023-03-15  9:22           ` Jiri Pirko
2023-03-16 12:31             ` Jiri Pirko
2023-03-28 15:22             ` Vadim Fedorenko
2023-04-01 12:49               ` Jiri Pirko
2023-04-03 18:18             ` Jakub Kicinski
2023-04-09  7:51               ` Jiri Pirko
     [not found]                 ` <20230410153149.602c6bad@kernel.org>
2023-04-16 16:23                   ` Jiri Pirko
2023-04-17 15:53                     ` Vadim Fedorenko
     [not found]                     ` <20230417124942.4305abfa@kernel.org>
     [not found]                       ` <ZFDPaXlJainSOqmV@nanopsycho>
     [not found]                         ` <20230502083244.19543d26@kernel.org>
2023-05-03  7:56                           ` Jiri Pirko
2023-05-04  2:16                             ` Jakub Kicinski
2023-05-04 11:00                               ` Jiri Pirko
2023-05-04 11:14                                 ` Jiri Pirko
2023-05-04 16:04                                 ` Jakub Kicinski
2023-05-04 17:51                                   ` Jiri Pirko
2023-05-04 18:44                                     ` Jakub Kicinski
2023-05-05 10:41                                       ` Jiri Pirko
2023-05-05 15:35                                         ` Jakub Kicinski
2023-05-07  7:58                                           ` Jiri Pirko
2023-05-08  6:50                                             ` Paolo Abeni
2023-05-08 12:17                                               ` Jiri Pirko
2023-05-08 19:42                                                 ` Jakub Kicinski
2023-05-09  7:53                                                   ` Jiri Pirko
2023-05-09 14:52                                                     ` Jakub Kicinski
2023-05-09 15:21                                                       ` Jiri Pirko
2023-05-09 17:53                                                         ` Jakub Kicinski
2023-05-10  6:17                                                           ` Jiri Pirko
2023-03-14 16:43       ` Kubalewski, Arkadiusz
2023-03-15 12:14         ` Jiri Pirko
2023-03-14  9:30   ` Jiri Pirko
2023-03-14 15:45   ` Jiri Pirko
2023-03-14 18:35     ` Kubalewski, Arkadiusz
2023-03-15 14:43       ` Jiri Pirko
2023-03-15 15:29   ` Jiri Pirko
2023-03-16 12:20   ` Jiri Pirko
2023-03-16 12:37   ` Jiri Pirko
2023-03-16 13:53   ` Jiri Pirko
2023-03-16 16:16   ` Jiri Pirko
2023-03-17 16:21   ` Jiri Pirko
2023-03-20 10:24   ` Jiri Pirko
2023-03-21 13:34   ` Jiri Pirko
2023-03-23 11:18   ` Jiri Pirko [this message]
2023-03-24  9:29   ` Jiri Pirko
2023-03-12  2:28 ` [PATCH RFC v6 3/6] dpll: documentation on DPLL subsystem interface Vadim Fedorenko
2023-03-14 16:14   ` Jiri Pirko
2023-04-03 10:21     ` Kubalewski, Arkadiusz
2023-03-16 13:46   ` Jiri Pirko
2023-04-03 10:23     ` Kubalewski, Arkadiusz
2023-03-12  2:28 ` [PATCH RFC v6 4/6] ice: add admin commands to access cgu configuration Vadim Fedorenko
2023-03-12  2:28 ` [PATCH RFC v6 5/6] ice: implement dpll interface to control cgu Vadim Fedorenko
2023-03-12  2:28 ` [PATCH RFC v6 6/6] ptp_ocp: implement DPLL ops Vadim Fedorenko
2023-03-14 10:05   ` Jiri Pirko
2023-03-15  0:10     ` Vadim Fedorenko
2023-03-15 12:24       ` Jiri Pirko
2023-03-31 23:28         ` Vadim Fedorenko
2023-04-01 12:53           ` Jiri Pirko
2023-03-15 15:34   ` Jiri Pirko
2023-03-15 15:52     ` Vadim Fedorenko
2023-03-16 12:12   ` Jiri Pirko
2023-03-13 12:20 ` [PATCH RFC v6 0/6] Create common DPLL/clock configuration API Jiri Pirko
2023-03-13 15:33   ` Vadim Fedorenko
2023-03-13 16:22     ` Jiri Pirko
2023-03-13 16:31       ` Vadim Fedorenko
2023-03-17 16:10     ` Jiri Pirko
2023-03-18  5:01       ` Jakub Kicinski
2023-03-23 11:21 ` Jiri Pirko
2023-03-23 18:00   ` Vadim Fedorenko
2023-03-26 17:00 ` [patch dpll-rfc 0/7] dpll: initial patchset extension by mlx5 implementation Jiri Pirko
2023-03-26 17:00   ` [patch dpll-rfc 1/7] dpll: make ops function args const Jiri Pirko
2023-03-26 17:00   ` [patch dpll-rfc 2/7] dpll: allow to call device register multiple times Jiri Pirko
2023-03-26 17:00   ` [patch dpll-rfc 3/7] dpll: introduce a helper to get first dpll ref and use it Jiri Pirko
2023-03-26 17:00   ` [patch dpll-rfc 4/7] dpll: allow to call pin register multiple times Jiri Pirko
2023-03-26 17:00   ` [patch dpll-rfc 5/7] dpll: export dpll_pin_notify() Jiri Pirko
2023-03-26 17:00   ` [patch dpll-rfc 6/7] netdev: expose DPLL pin handle for netdevice Jiri Pirko
2023-03-26 17:00   ` [patch dpll-rfc 7/7] mlx5: Implement SyncE support using DPLL infrastructure Jiri Pirko
2023-03-28 16:36   ` [patch dpll-rfc 0/7] dpll: initial patchset extension by mlx5 implementation Vadim Fedorenko
2023-04-01 12:54     ` Jiri Pirko

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=ZBw1dID2U9D7wMyy@nanopsycho \
    --to=jiri@resnulli.us \
    --cc=arkadiusz.kubalewski@intel.com \
    --cc=jonathan.lemon@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=michal.michalik@intel.com \
    --cc=milena.olech@intel.com \
    --cc=mschmidt@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=poros@redhat.com \
    --cc=vadfed@meta.com \
    --cc=vadim.fedorenko@linux.dev \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).