[patch 07/13] ptp: Split out PTP_SYS_OFFSET ioctl code

Thomas Gleixner posted 13 patches 3 months, 2 weeks ago
There is a newer version of this series
[patch 07/13] ptp: Split out PTP_SYS_OFFSET ioctl code
Posted by Thomas Gleixner 3 months, 2 weeks ago
Continue the ptp_ioctl() cleanup by splitting out the PTP_SYS_OFFSET ioctl
code into a helper function.

Convert it to __free() to avoid gotos.

No functional change intended.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/ptp/ptp_chardev.c |   78 +++++++++++++++++++++++-----------------------
 1 file changed, 40 insertions(+), 38 deletions(-)

--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -357,18 +357,54 @@ static long ptp_sys_offset_extended(stru
 	return copy_to_user(arg, extoff, sizeof(*extoff)) ? -EFAULT : 0;
 }
 
+static long ptp_sys_offset(struct ptp_clock *ptp, void __user *arg)
+{
+	struct ptp_sys_offset *sysoff __free(kfree) = NULL;
+	struct ptp_clock_time *pct;
+	struct timespec64 ts;
+
+	sysoff = memdup_user(arg, sizeof(*sysoff));
+	if (IS_ERR(sysoff))
+		return PTR_ERR(sysoff);
+
+	if (sysoff->n_samples > PTP_MAX_SAMPLES)
+		return -EINVAL;
+
+	pct = &sysoff->ts[0];
+	for (unsigned int i = 0; i < sysoff->n_samples; i++) {
+		struct ptp_clock_info *ops = ptp->info;
+		int err;
+
+		ktime_get_real_ts64(&ts);
+		pct->sec = ts.tv_sec;
+		pct->nsec = ts.tv_nsec;
+		pct++;
+		if (ops->gettimex64)
+			err = ops->gettimex64(ops, &ts, NULL);
+		else
+			err = ops->gettime64(ops, &ts);
+		if (err)
+			return err;
+		pct->sec = ts.tv_sec;
+		pct->nsec = ts.tv_nsec;
+		pct++;
+	}
+	ktime_get_real_ts64(&ts);
+	pct->sec = ts.tv_sec;
+	pct->nsec = ts.tv_nsec;
+
+	return copy_to_user(arg, sysoff, sizeof(*sysoff)) ? -EFAULT : 0;
+}
+
 long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
 	       unsigned long arg)
 {
 	struct ptp_clock *ptp =
 		container_of(pccontext->clk, struct ptp_clock, clock);
 	struct ptp_clock_info *ops = ptp->info;
-	struct ptp_sys_offset *sysoff = NULL;
 	struct timestamp_event_queue *tsevq;
-	struct ptp_clock_time *pct;
 	unsigned int i, pin_index;
 	struct ptp_pin_desc pd;
-	struct timespec64 ts;
 	void __user *argptr;
 	int err = 0;
 
@@ -411,38 +447,7 @@ long ptp_ioctl(struct posix_clock_contex
 
 	case PTP_SYS_OFFSET:
 	case PTP_SYS_OFFSET2:
-		sysoff = memdup_user((void __user *)arg, sizeof(*sysoff));
-		if (IS_ERR(sysoff)) {
-			err = PTR_ERR(sysoff);
-			sysoff = NULL;
-			break;
-		}
-		if (sysoff->n_samples > PTP_MAX_SAMPLES) {
-			err = -EINVAL;
-			break;
-		}
-		pct = &sysoff->ts[0];
-		for (i = 0; i < sysoff->n_samples; i++) {
-			ktime_get_real_ts64(&ts);
-			pct->sec = ts.tv_sec;
-			pct->nsec = ts.tv_nsec;
-			pct++;
-			if (ops->gettimex64)
-				err = ops->gettimex64(ops, &ts, NULL);
-			else
-				err = ops->gettime64(ops, &ts);
-			if (err)
-				goto out;
-			pct->sec = ts.tv_sec;
-			pct->nsec = ts.tv_nsec;
-			pct++;
-		}
-		ktime_get_real_ts64(&ts);
-		pct->sec = ts.tv_sec;
-		pct->nsec = ts.tv_nsec;
-		if (copy_to_user((void __user *)arg, sysoff, sizeof(*sysoff)))
-			err = -EFAULT;
-		break;
+		return ptp_sys_offset(ptp, argptr);
 
 	case PTP_PIN_GETFUNC:
 	case PTP_PIN_GETFUNC2:
@@ -530,9 +535,6 @@ long ptp_ioctl(struct posix_clock_contex
 		err = -ENOTTY;
 		break;
 	}
-
-out:
-	kfree(sysoff);
 	return err;
 }
Re: [patch 07/13] ptp: Split out PTP_SYS_OFFSET ioctl code
Posted by Vadim Fedorenko 3 months, 2 weeks ago
On 20/06/2025 14:24, Thomas Gleixner wrote:
> Continue the ptp_ioctl() cleanup by splitting out the PTP_SYS_OFFSET ioctl
> code into a helper function.
> 
> Convert it to __free() to avoid gotos.
> 
> No functional change intended.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
>   drivers/ptp/ptp_chardev.c |   78 +++++++++++++++++++++++-----------------------
>   1 file changed, 40 insertions(+), 38 deletions(-)
> 
> --- a/drivers/ptp/ptp_chardev.c
> +++ b/drivers/ptp/ptp_chardev.c
> @@ -357,18 +357,54 @@ static long ptp_sys_offset_extended(stru
>   	return copy_to_user(arg, extoff, sizeof(*extoff)) ? -EFAULT : 0;
>   }
>   
> +static long ptp_sys_offset(struct ptp_clock *ptp, void __user *arg)
> +{
> +	struct ptp_sys_offset *sysoff __free(kfree) = NULL;
> +	struct ptp_clock_time *pct;
> +	struct timespec64 ts;
> +
> +	sysoff = memdup_user(arg, sizeof(*sysoff));
> +	if (IS_ERR(sysoff))
> +		return PTR_ERR(sysoff);
> +
> +	if (sysoff->n_samples > PTP_MAX_SAMPLES)
> +		return -EINVAL;
> +
> +	pct = &sysoff->ts[0];
> +	for (unsigned int i = 0; i < sysoff->n_samples; i++) {
> +		struct ptp_clock_info *ops = ptp->info;

Looks like *ops initialization can be moved outside of the loop.

> +		int err;
> +
> +		ktime_get_real_ts64(&ts);
> +		pct->sec = ts.tv_sec;
> +		pct->nsec = ts.tv_nsec;
> +		pct++;
> +		if (ops->gettimex64)
> +			err = ops->gettimex64(ops, &ts, NULL);
> +		else
> +			err = ops->gettime64(ops, &ts);
> +		if (err)
> +			return err;
> +		pct->sec = ts.tv_sec;
> +		pct->nsec = ts.tv_nsec;
> +		pct++;
> +	}
> +	ktime_get_real_ts64(&ts);
> +	pct->sec = ts.tv_sec;
> +	pct->nsec = ts.tv_nsec;
> +
> +	return copy_to_user(arg, sysoff, sizeof(*sysoff)) ? -EFAULT : 0;
> +}
> +

[...]
Re: [patch 07/13] ptp: Split out PTP_SYS_OFFSET ioctl code
Posted by Thomas Gleixner 3 months, 2 weeks ago
On Sat, Jun 21 2025 at 21:14, Vadim Fedorenko wrote:
> On 20/06/2025 14:24, Thomas Gleixner wrote:
>> +	pct = &sysoff->ts[0];
>> +	for (unsigned int i = 0; i < sysoff->n_samples; i++) {
>> +		struct ptp_clock_info *ops = ptp->info;
>
> Looks like *ops initialization can be moved outside of the loop.

Well it can, but does it matter? No, because this is only a coding
artifact. The compiler can evaluate ptp->info inside of the loop at his
own peril even on both usage sites.

Though what's more important is that from a context point of view, ops
belongs into the loop, because that's where it is used and not outside,
no?

Thanks,

        tglx
Re: [patch 07/13] ptp: Split out PTP_SYS_OFFSET ioctl code
Posted by Vadim Fedorenko 3 months, 2 weeks ago
On 21/06/2025 21:42, Thomas Gleixner wrote:
> On Sat, Jun 21 2025 at 21:14, Vadim Fedorenko wrote:
>> On 20/06/2025 14:24, Thomas Gleixner wrote:
>>> +	pct = &sysoff->ts[0];
>>> +	for (unsigned int i = 0; i < sysoff->n_samples; i++) {
>>> +		struct ptp_clock_info *ops = ptp->info;
>>
>> Looks like *ops initialization can be moved outside of the loop.
> 
> Well it can, but does it matter? No, because this is only a coding
> artifact. The compiler can evaluate ptp->info inside of the loop at his
> own peril even on both usage sites.
> 
> Though what's more important is that from a context point of view, ops
> belongs into the loop, because that's where it is used and not outside,
> no?

Well, in the original code it was always outside of any loops. And the
scope a bit bigger, all these functions work with ptp_clock object, so
the context is really subjective. It just looks a bit weird to de-
reference something, which is known not to change, every iteration. Of
course the compiler is smart enough to optimize it, but still..


> Thanks,
> 
>          tglx