From patchwork Fri Jan 20 12:20:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Tosatti X-Patchwork-Id: 9528205 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C56A260459 for ; Fri, 20 Jan 2017 12:28:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B3E6C28616 for ; Fri, 20 Jan 2017 12:28:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A5A4A2861F; Fri, 20 Jan 2017 12:28:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 25EC428616 for ; Fri, 20 Jan 2017 12:28:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752187AbdATM2s (ORCPT ); Fri, 20 Jan 2017 07:28:48 -0500 Received: from mx1.redhat.com ([209.132.183.28]:43926 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751977AbdATM1k (ORCPT ); Fri, 20 Jan 2017 07:27:40 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 276318124F; Fri, 20 Jan 2017 12:27:41 +0000 (UTC) Received: from amt.cnet (vpn1-4-171.gru2.redhat.com [10.97.4.171]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v0KCRdAm006099; Fri, 20 Jan 2017 07:27:40 -0500 Received: from amt.cnet (localhost [127.0.0.1]) by amt.cnet (Postfix) with ESMTP id 77F7D100904; Fri, 20 Jan 2017 10:27:07 -0200 (BRST) Received: (from marcelo@localhost) by amt.cnet (8.14.7/8.14.7/Submit) id v0KCR7Vj020330; Fri, 20 Jan 2017 10:27:07 -0200 Message-Id: <20170120122503.746158230@redhat.com> User-Agent: quilt/0.60-1 Date: Fri, 20 Jan 2017 10:20:29 -0200 From: Marcelo Tosatti To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Paolo Bonzini , Radim Krcmar , Richard Cochran , Miroslav Lichvar , Marcelo Tosatti Subject: [patch 4/5] PTP: add PTP_SYS_OFFSET emulation via cross timestamps infrastructure References: <20170120122025.665985919@redhat.com> Content-Disposition: inline; filename=ptp-add-sysoffset-callback X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Fri, 20 Jan 2017 12:27:41 +0000 (UTC) Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Emulate PTP_SYS_OFFSET by using an arithmetic mean of the realtime samples from ->getcrosststamp callback. Signed-off-by: Marcelo Tosatti --- drivers/ptp/ptp_chardev.c | 6 ++ include/linux/ptp_clock_kernel.h | 5 ++ include/linux/timekeeping_ptp.h | 10 ++++ kernel/time/timekeeping.c | 79 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+) -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: kvm-ptpdriver/drivers/ptp/ptp_chardev.c =================================================================== --- kvm-ptpdriver.orig/drivers/ptp/ptp_chardev.c 2017-01-19 15:34:52.181338789 -0200 +++ kvm-ptpdriver/drivers/ptp/ptp_chardev.c 2017-01-19 15:35:31.705421911 -0200 @@ -23,6 +23,7 @@ #include #include #include +#include #include "ptp_private.h" @@ -219,6 +220,11 @@ err = -EINVAL; break; } + + if (ptp->info->emulate_ptp_sys_offset_mean) { + err = emulate_ptp_sys_offset(ptp->info, sysoff, arg); + break; + } pct = &sysoff->ts[0]; for (i = 0; i < sysoff->n_samples; i++) { getnstimeofday64(&ts); Index: kvm-ptpdriver/include/linux/ptp_clock_kernel.h =================================================================== --- kvm-ptpdriver.orig/include/linux/ptp_clock_kernel.h 2017-01-19 15:34:52.181338789 -0200 +++ kvm-ptpdriver/include/linux/ptp_clock_kernel.h 2017-01-19 15:35:31.706421913 -0200 @@ -99,6 +99,10 @@ * parameter func: the desired function to use. * parameter chan: the function channel index to use. * + * @emulate_ptp_sys_offset_mean: Emulate PTP_SYS_OFFSET ioctl + * using arithmetic mean of series of PTP_SYS_OFFSET_PRECISE + * ioctl. + * * Drivers should embed their ptp_clock_info within a private * structure, obtaining a reference to it using container_of(). * @@ -115,6 +119,7 @@ int n_pins; int pps; struct ptp_pin_desc *pin_config; + bool emulate_ptp_sys_offset_mean; int (*adjfine)(struct ptp_clock_info *ptp, long scaled_ppm); int (*adjfreq)(struct ptp_clock_info *ptp, s32 delta); int (*adjtime)(struct ptp_clock_info *ptp, s64 delta); Index: kvm-ptpdriver/include/linux/timekeeping_ptp.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ kvm-ptpdriver/include/linux/timekeeping_ptp.h 2017-01-19 15:35:31.706421913 -0200 @@ -0,0 +1,10 @@ +#ifndef _LINUX_TIMEKEEPING_PTP_H +#define _LINUX_TIMEKEEPING_PTP_H + +#include +#include + +extern int emulate_ptp_sys_offset(struct ptp_clock_info *info, + struct ptp_sys_offset *sysoff, + unsigned long arg); +#endif Index: kvm-ptpdriver/kernel/time/timekeeping.c =================================================================== --- kvm-ptpdriver.orig/kernel/time/timekeeping.c 2017-01-19 15:34:52.181338789 -0200 +++ kvm-ptpdriver/kernel/time/timekeeping.c 2017-01-20 09:29:13.978434149 -0200 @@ -23,6 +23,10 @@ #include #include #include +#include +#include +#include +#include #include "tick-internal.h" #include "ntp_internal.h" @@ -1168,6 +1172,81 @@ } EXPORT_SYMBOL_GPL(get_device_system_crosststamp); +static void mean_sys_realtime(struct system_device_crosststamp *xtstamp, + struct system_device_crosststamp *n_xtstamp, + struct ptp_clock_time *pct) +{ + ktime_t sys_realtime, n_sys_realtime; + struct timespec ts; + u64 ns; + + /* estimate realtime with arithmetic mean of two crosststamp samples */ + sys_realtime = xtstamp->sys_realtime; + n_sys_realtime = n_xtstamp->sys_realtime; + ns = ktime_divns(ktime_add(sys_realtime, n_sys_realtime), 2); + ts = ktime_to_timespec(ns_to_ktime(ns)); + pct->sec = ts.tv_sec; + pct->nsec = ts.tv_nsec; +} + +int emulate_ptp_sys_offset(struct ptp_clock_info *info, + struct ptp_sys_offset *sysoff, + unsigned long arg) +{ + unsigned long flags; + int i, err, len; + int n_samples; + struct system_device_crosststamp *xtstamps, *xtstamp, *n_xtstamp; + struct ptp_clock_time *pct; + + n_samples = sysoff->n_samples + 2; + + len = sizeof(struct system_device_crosststamp); + xtstamps = kzalloc(len * n_samples, GFP_KERNEL); + if (xtstamps == NULL) + return -ENOMEM; + + /* stop update_wall_time, settimeofday */ + raw_spin_lock_irqsave(&timekeeper_lock, flags); + + xtstamp = xtstamps; + for (i = 0; i < n_samples; i++) { + err = info->getcrosststamp(info, xtstamp); + if (err) { + kfree(xtstamps); + raw_spin_unlock_irqrestore(&timekeeper_lock, flags); + return err; + } + xtstamp++; + } + + pct = &sysoff->ts[0]; + xtstamp = n_xtstamp = xtstamps; + n_xtstamp++; + for (i = 0; i < sysoff->n_samples; i++) { + struct timespec ts; + + mean_sys_realtime(xtstamp, n_xtstamp, pct); + pct++; + + ts = ktime_to_timespec(n_xtstamp->device); + pct->sec = ts.tv_sec; + pct->nsec = ts.tv_nsec; + pct++; + xtstamp++; + n_xtstamp++; + } + + mean_sys_realtime(xtstamp, n_xtstamp, pct); + raw_spin_unlock_irqrestore(&timekeeper_lock, flags); + kfree(xtstamps); + if (copy_to_user((void __user *)arg, sysoff, sizeof(*sysoff))) + return -EFAULT; + + return 0; +} +EXPORT_SYMBOL(emulate_ptp_sys_offset); + /** * do_gettimeofday - Returns the time of day in a timeval * @tv: pointer to the timeval to be set