hyperv-fixes for 5.9-rc3
-----BEGIN PGP SIGNATURE----- iQFHBAABCAAxFiEEIbPD0id6easf0xsudhRwX5BBoF4FAl9GaMcTHHdlaS5saXVA a2VybmVsLm9yZwAKCRB2FHBfkEGgXi1yCADJRrElI0kP5KAJJ6dQCXzhs8PX5rZG rDNguVWy3Gocsngrn+8fQVHGdQmO/Y0nqVo3Y4zV1NtWx4MqO6pFtDc1kCYOSgws bgHLwm16qHYDar1oBrplgEny1U9FVs4zOIw7diUJeOctX7TDu2MXrjl9F+XvlGqJ xf90H/h8VdODh0rOWY5i6+RuM/ztcVwvqjne/uxhx5Gl/sO+Piwp18AL7C2ItOC4 b+ZnM3c1plAetTqN1taGiYTqlKCdvSoDtVkySMseLPYeVoVt3CwZTNiX6GlWJzbw RujSrXimOmsxWEVi0qsI0PG6rQRCO+6ojQHEj7amjBR7C1yVnxKeJCM9 =/xNi -----END PGP SIGNATURE----- Merge tag 'hyperv-fixes-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux Pull hyperv fixes from Wei Liu: "Two patches from Vineeth to improve Hyper-V timesync facility" * tag 'hyperv-fixes-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux: hv_utils: drain the timesync packets on onchannelcallback hv_utils: return error if host timesysnc update is stale
This commit is contained in:
commit
51c4518ab7
@ -282,26 +282,52 @@ static struct {
|
|||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
} host_ts;
|
} host_ts;
|
||||||
|
|
||||||
static struct timespec64 hv_get_adj_host_time(void)
|
static inline u64 reftime_to_ns(u64 reftime)
|
||||||
{
|
{
|
||||||
struct timespec64 ts;
|
return (reftime - WLTIMEDELTA) * 100;
|
||||||
u64 newtime, reftime;
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hard coded threshold for host timesync delay: 600 seconds
|
||||||
|
*/
|
||||||
|
static const u64 HOST_TIMESYNC_DELAY_THRESH = 600 * (u64)NSEC_PER_SEC;
|
||||||
|
|
||||||
|
static int hv_get_adj_host_time(struct timespec64 *ts)
|
||||||
|
{
|
||||||
|
u64 newtime, reftime, timediff_adj;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
spin_lock_irqsave(&host_ts.lock, flags);
|
spin_lock_irqsave(&host_ts.lock, flags);
|
||||||
reftime = hv_read_reference_counter();
|
reftime = hv_read_reference_counter();
|
||||||
newtime = host_ts.host_time + (reftime - host_ts.ref_time);
|
|
||||||
ts = ns_to_timespec64((newtime - WLTIMEDELTA) * 100);
|
/*
|
||||||
|
* We need to let the caller know that last update from host
|
||||||
|
* is older than the max allowable threshold. clock_gettime()
|
||||||
|
* and PTP ioctl do not have a documented error that we could
|
||||||
|
* return for this specific case. Use ESTALE to report this.
|
||||||
|
*/
|
||||||
|
timediff_adj = reftime - host_ts.ref_time;
|
||||||
|
if (timediff_adj * 100 > HOST_TIMESYNC_DELAY_THRESH) {
|
||||||
|
pr_warn_once("TIMESYNC IC: Stale time stamp, %llu nsecs old\n",
|
||||||
|
(timediff_adj * 100));
|
||||||
|
ret = -ESTALE;
|
||||||
|
}
|
||||||
|
|
||||||
|
newtime = host_ts.host_time + timediff_adj;
|
||||||
|
*ts = ns_to_timespec64(reftime_to_ns(newtime));
|
||||||
spin_unlock_irqrestore(&host_ts.lock, flags);
|
spin_unlock_irqrestore(&host_ts.lock, flags);
|
||||||
|
|
||||||
return ts;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hv_set_host_time(struct work_struct *work)
|
static void hv_set_host_time(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct timespec64 ts = hv_get_adj_host_time();
|
|
||||||
|
|
||||||
do_settimeofday64(&ts);
|
struct timespec64 ts;
|
||||||
|
|
||||||
|
if (!hv_get_adj_host_time(&ts))
|
||||||
|
do_settimeofday64(&ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -361,10 +387,23 @@ static void timesync_onchannelcallback(void *context)
|
|||||||
struct ictimesync_ref_data *refdata;
|
struct ictimesync_ref_data *refdata;
|
||||||
u8 *time_txf_buf = util_timesynch.recv_buffer;
|
u8 *time_txf_buf = util_timesynch.recv_buffer;
|
||||||
|
|
||||||
vmbus_recvpacket(channel, time_txf_buf,
|
/*
|
||||||
HV_HYP_PAGE_SIZE, &recvlen, &requestid);
|
* Drain the ring buffer and use the last packet to update
|
||||||
|
* host_ts
|
||||||
|
*/
|
||||||
|
while (1) {
|
||||||
|
int ret = vmbus_recvpacket(channel, time_txf_buf,
|
||||||
|
HV_HYP_PAGE_SIZE, &recvlen,
|
||||||
|
&requestid);
|
||||||
|
if (ret) {
|
||||||
|
pr_warn_once("TimeSync IC pkt recv failed (Err: %d)\n",
|
||||||
|
ret);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!recvlen)
|
||||||
|
break;
|
||||||
|
|
||||||
if (recvlen > 0) {
|
|
||||||
icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[
|
icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[
|
||||||
sizeof(struct vmbuspipe_hdr)];
|
sizeof(struct vmbuspipe_hdr)];
|
||||||
|
|
||||||
@ -622,9 +661,7 @@ static int hv_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
|
|||||||
|
|
||||||
static int hv_ptp_gettime(struct ptp_clock_info *info, struct timespec64 *ts)
|
static int hv_ptp_gettime(struct ptp_clock_info *info, struct timespec64 *ts)
|
||||||
{
|
{
|
||||||
*ts = hv_get_adj_host_time();
|
return hv_get_adj_host_time(ts);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ptp_clock_info ptp_hyperv_info = {
|
static struct ptp_clock_info ptp_hyperv_info = {
|
||||||
|
Loading…
Reference in New Issue
Block a user