mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Dipen Patel <dipenp@nvidia.com>
To: Hillf Danton <hdanton@sina.com>
Cc: linux-kernel@vger.kernel.org, robh+dt@kernel.org
Subject: Re: [PATCH v4 02/11] drivers: Add hardware timestamp engine (HTE)
Date: Tue, 22 Mar 2022 11:07:32 -0700	[thread overview]
Message-ID: <c1f55917-c7b9-140e-29ed-937f1c2b656e@nvidia.com> (raw)
In-Reply-To: <20220202035259.1875-1-hdanton@sina.com>

Hi Hillf,

The reason I used kernel thread as it will not be shared by others and can deliver payload at the earliest of course when scheduler decides to run it. The workqueue system_unbound_wq is shared by multiple subsystem and depends on the prior works scheduled in that queue. Is it ok if I retain thread approach?

On 2/1/22 7:52 PM, Hillf Danton wrote:
> On Tue, 1 Feb 2022 14:26:21 -0800 Dipen Patel wrote:
>> +/**
>> + * hte_release_ts() - Release and disable timestamp for the given desc.
>> + *
>> + * @desc: timestamp descriptor.
>> + *
>> + * Context: debugfs_remove_recursive() function call may use sleeping locks,
>> + *	    not suitable from atomic context.
>> + * Returns: 0 on success or a negative error code on failure.
>> + */
>> +int hte_release_ts(struct hte_ts_desc *desc)
>> +{
>> +	int ret = 0;
>> +	unsigned long flag;
>> +	struct hte_device *gdev;
>> +	struct hte_ts_info *ei;
>> +
>> +	if (!desc)
>> +		return -EINVAL;
>> +
>> +	ei = desc->hte_data;
>> +
>> +	if (!ei || !ei->gdev)
>> +		return -EINVAL;
>> +
>> +	gdev = ei->gdev;
>> +
>> +	mutex_lock(&ei->req_mlock);
>> +
>> +	if (!test_bit(HTE_TS_REGISTERED, &ei->flags)) {
>> +		dev_info(gdev->sdev, "id:%d is not registered",
>> +			 desc->attr.line_id);
>> +		ret = -EUSERS;
>> +		goto unlock;
>> +	}
>> +
>> +	ret = gdev->chip->ops->release(gdev->chip, desc, ei->xlated_id);
>> +	if (ret) {
>> +		dev_err(gdev->sdev, "id: %d free failed\n",
>> +			desc->attr.line_id);
>> +		goto unlock;
>> +	}
>> +
>> +	kfree(ei->line_name);
>> +
>> +	debugfs_remove_recursive(ei->ts_dbg_root);
>> +
>> +	spin_lock_irqsave(&ei->slock, flag);
>> +
>> +	atomic_dec(&gdev->ts_req);
>> +	atomic_set(&ei->dropped_ts, 0);
>> +
>> +	ei->seq = 1;
>> +	desc->hte_data = NULL;
>> +
>> +	clear_bit(HTE_TS_REGISTERED, &ei->flags);
>> +
>> +	spin_unlock_irqrestore(&ei->slock, flag);
>> +
>> +	if (ei->tcb) {
>> +		kthread_stop(ei->thread);
>> +		put_task_struct(ei->thread);
> The code becomes simpler if the thread is replaced with a workqueue work
> alternatively.
>
> 		cancel_work_sync(&ei->cb_work);
>> +	}
>> +
>> +	ei->cb = NULL;
>> +	ei->tcb = NULL;
>> +	ei->thread = NULL;
>> +	ei->cl_data = NULL;
>> +
>> +	module_put(gdev->owner);
>> +unlock:
>> +	mutex_unlock(&ei->req_mlock);
>> +	dev_dbg(gdev->sdev, "release id: %d\n", desc->attr.line_id);
>> +
>> +	return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(hte_release_ts);
> ...
>> +
>> +static int _hte_threadfn(void *data)
>> +{
>> +	struct hte_ts_info *ei = data;
>> +
>> +	while (!_hte_wait_for_ts_data(ei))
>> +		ei->tcb(ei->cl_data);
>> +
>> +	return 0;
>> +}
>> +
> static void hte_do_cb_work(struct work_struct *w)
> {
> 	struct hte_ts_info *ei = container_of(w, struct hte_ts_info, cb_work);
>
> 	ei->tcb(ei->cl_data);
> }
>
>> +static int _hte_setup_thread(struct hte_ts_info *ei, u32 id)
>> +{
>> +	struct task_struct *t;
>> +
>> +	t = kthread_create(_hte_threadfn, ei, "hte-%u", id);
>> +	if (IS_ERR(t))
>> +		return PTR_ERR(t);
>> +
>> +	ei->thread = get_task_struct(t);
>> +
>> +	return 0;
>> +}
>> +
>> +static int ___hte_req_ts(struct hte_device *gdev, struct hte_ts_desc *desc,
>> +			 u32 xlated_id, hte_ts_cb_t cb,
>> +			 hte_ts_threaded_cb_t tcb, void *data)
>> +{
>> +	struct hte_ts_info *ei;
>> +	int ret;
>> +
>> +	if (!try_module_get(gdev->owner))
>> +		return -ENODEV;
>> +
>> +	ei = &gdev->ei[xlated_id];
>> +	ei->xlated_id = xlated_id;
>> +
>> +	/*
>> +	 * There is a chance that multiple consumers requesting same entity,
>> +	 * lock here.
>> +	 */
>> +	mutex_lock(&ei->req_mlock);
>> +
>> +	if (test_bit(HTE_TS_REGISTERED, &ei->flags)) {
>> +		dev_dbg(gdev->chip->dev, "id:%u is already registered",
>> +			xlated_id);
>> +		ret = -EUSERS;
>> +		goto unlock;
>> +	}
>> +
>> +	ei->cb = cb;
>> +	ei->tcb = tcb;
>> +	if (tcb) {
> 		INIT_WORK(&ei->cb_work, hte_do_cb_work);
>
>> +		ret = _hte_setup_thread(ei, xlated_id);
>> +		if (ret < 0) {
>> +			dev_err(gdev->chip->dev, "setting thread failed\n");
>> +			goto unlock;
>> +		}
>> +	}
>> +
>> +	ret = gdev->chip->ops->request(gdev->chip, desc, xlated_id);
>> +	if (ret < 0) {
>> +		dev_err(gdev->chip->dev, "ts request failed\n");
>> +		goto unlock;
>> +	}
>> +
>> +	desc->hte_data = ei;
>> +	ei->cl_data = data;
>> +	ei->seq = 1;
>> +
>> +	atomic_inc(&gdev->ts_req);
>> +
>> +	ei->line_name = NULL;
>> +	if (!desc->attr.name) {
>> +		ei->line_name = kzalloc(HTE_TS_NAME_LEN, GFP_KERNEL);
>> +		if (ei->line_name)
>> +			scnprintf(ei->line_name, HTE_TS_NAME_LEN, "ts_%u",
>> +				  desc->attr.line_id);
>> +	}
>> +
>> +	hte_ts_dbgfs_init(desc->attr.name == NULL ?
>> +			  ei->line_name : desc->attr.name, ei);
>> +	set_bit(HTE_TS_REGISTERED, &ei->flags);
>> +
>> +	mutex_unlock(&ei->req_mlock);
>> +
>> +	dev_dbg(gdev->chip->dev, "id: %u, xlated id:%u",
>> +		desc->attr.line_id, xlated_id);
>> +
>> +	return 0;
>> +
>> +unlock:
>> +	module_put(gdev->owner);
>> +	mutex_unlock(&ei->req_mlock);
>> +
>> +	return ret;
>> +}
> ...
>> +/**
>> + * hte_push_ts_ns() - Push timestamp data in nanoseconds.
>> + *
>> + * It is used by the provider to push timestamp data.
>> + *
>> + * @chip: The HTE chip, used during the registration.
>> + * @xlated_id: entity id understood by both subsystem and provider, this is
>> + * obtained from xlate callback during request API.
>> + * @data: timestamp data.
>> + *
>> + * Returns: 0 on success or a negative error code on failure.
>> + */
>> +int hte_push_ts_ns(const struct hte_chip *chip, u32 xlated_id,
>> +		   struct hte_ts_data *data)
>> +{
>> +	hte_return_t ret;
>> +	int st = 0;
>> +	struct hte_ts_info *ei;
>> +	unsigned long flag;
>> +
>> +	if (!chip || !data || !chip->gdev)
>> +		return -EINVAL;
>> +
>> +	if (xlated_id > chip->nlines)
>> +		return -EINVAL;
>> +
>> +	ei = &chip->gdev->ei[xlated_id];
>> +
>> +	spin_lock_irqsave(&ei->slock, flag);
>> +
>> +	/* timestamp sequence counter */
>> +	data->seq = ei->seq++;
>> +
>> +	if (!test_bit(HTE_TS_REGISTERED, &ei->flags) ||
>> +	    test_bit(HTE_TS_DISABLE, &ei->flags)) {
>> +		dev_dbg(chip->dev, "Unknown timestamp push\n");
>> +		atomic_inc(&ei->dropped_ts);
>> +		st = -EINVAL;
>> +		goto unlock;
>> +	}
>> +
>> +	ret = ei->cb(data, ei->cl_data);
>> +	if (ret == HTE_RUN_THREADED_CB && ei->thread) {
>> +		if (test_and_set_bit(HTE_CB_RUN_THREAD, &ei->hte_cb_flags))
>> +			goto unlock;
>> +		else
>> +			wake_up_process(ei->thread);
> 			queue_work(system_unbound_wq, &ei->cb_work);
>> +	}
>> +
>> +unlock:
>> +	spin_unlock_irqrestore(&ei->slock, flag);
>> +
>> +	return st;
>> +}
>> +EXPORT_SYMBOL_GPL(hte_push_ts_ns);

      parent reply	other threads:[~2022-03-22 18:09 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-01 22:26 [PATCH v4 00/11] Intro to Hardware timestamping engine Dipen Patel
2022-02-01 22:26 ` [PATCH v4 01/11] Documentation: Add HTE subsystem guide Dipen Patel
2022-02-01 22:26 ` [PATCH v4 02/11] drivers: Add hardware timestamp engine (HTE) Dipen Patel
2022-02-01 22:26 ` [PATCH v4 03/11] hte: Add tegra194 HTE kernel provider Dipen Patel
2022-02-01 22:26 ` [PATCH v4 04/11] dt-bindings: Add HTE bindings Dipen Patel
2022-02-04 23:37   ` Rob Herring
2022-03-22 23:10     ` Dipen Patel
2022-02-01 22:26 ` [PATCH v4 05/11] hte: Add Tegra194 IRQ HTE test driver Dipen Patel
2022-02-01 22:26 ` [PATCH v4 06/11] gpiolib: Add HTE support Dipen Patel
2022-02-01 22:26 ` [PATCH v4 07/11] gpio: tegra186: Add HTE in gpio-tegra186 driver Dipen Patel
2022-02-01 22:26 ` [PATCH v4 08/11] gpiolib: cdev: Add hardware timestamp clock type Dipen Patel
2022-02-01 22:26 ` [PATCH v4 09/11] tools: gpio: Add new hardware " Dipen Patel
2022-02-01 22:26 ` [PATCH v4 10/11] hte: Add tegra GPIO HTE test driver Dipen Patel
2022-02-01 22:26 ` [PATCH v4 11/11] MAINTAINERS: Added HTE Subsystem Dipen Patel
     [not found] ` <20220202035259.1875-1-hdanton@sina.com>
2022-03-22 18:07   ` Dipen Patel [this message]

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=c1f55917-c7b9-140e-29ed-937f1c2b656e@nvidia.com \
    --to=dipenp@nvidia.com \
    --cc=hdanton@sina.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robh+dt@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®