From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752256AbcAFR2Q (ORCPT ); Wed, 6 Jan 2016 12:28:16 -0500 Received: from mail-yk0-f170.google.com ([209.85.160.170]:34959 "EHLO mail-yk0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752045AbcAFR2K (ORCPT ); Wed, 6 Jan 2016 12:28:10 -0500 MIME-Version: 1.0 In-Reply-To: <1452085234-10667-2-git-send-email-prarit@redhat.com> References: <1452085234-10667-1-git-send-email-prarit@redhat.com> <1452085234-10667-2-git-send-email-prarit@redhat.com> Date: Wed, 6 Jan 2016 09:28:09 -0800 Message-ID: Subject: Re: [PATCH 1/2] kernel, timekeeping, add trylock option to ktime_get_with_offset() From: John Stultz To: Prarit Bhargava Cc: lkml , Thomas Gleixner , Ingo Molnar , Xunlei Pang , Peter Zijlstra , Baolin Wang , Arnd Bergmann Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Jan 6, 2016 at 5:00 AM, Prarit Bhargava wrote: > -ktime_t ktime_get_with_offset(enum tk_offsets offs) > +ktime_t ktime_get_with_offset(enum tk_offsets offs, int trylock) > { > struct timekeeper *tk = &tk_core.timekeeper; > unsigned int seq; > ktime_t base, *offset = offsets[offs]; > s64 nsecs; > + unsigned long flags = 0; > + > + if (unlikely(!timekeeping_initialized)) > + return ktime_set(0, 0); > > WARN_ON(timekeeping_suspended); > > + if (trylock && !raw_spin_trylock_irqsave(&timekeeper_lock, flags)) > + return ktime_set(KTIME_MAX, 0); Wait.. this doesn't make sense. The timekeeper lock is only for reading. What I was suggesting to you off line is to have something that avoids spinning on the seqcounter should if a bug occurs and we IPI all the cpus, that we don't deadlock or block any printk messages. > + > do { > seq = read_seqcount_begin(&tk_core.seq); > base = ktime_add(tk->tkr_mono.base, *offset); > @@ -721,6 +730,9 @@ ktime_t ktime_get_with_offset(enum tk_offsets offs) > > } while (read_seqcount_retry(&tk_core.seq, seq)); So instead of the do/while() loop above... Something closer to: int __ktime_get_with_offset(enum tk_offsets offs, ktime_t* base, s64 *nsec) { unsigned int seq; seq = read_seqcount_begin(&tk_core.seq); *base = ktime_add(tk->tkr_mono.base, *offset); *nsecs = timekeeping_get_ns(&tk->tkr_mono); return read_seqcount_retry(&tk_core.seq, seq); } Then ktime_get_with_offset() would just call: ... while(__ktime_get_with_offset(offs, &base, &nsecs)) /*spin*/; return ktime_add_ns(base,nsecs); Then you add a simple: int ktime_try_get_with_offset(enum tk_offsets offs, ktime_t* ret) { ... if (__ktime_get_with_offset(offs, &base, &nsecs)) return -EAGAIN; *ret = ktime_add_ns(base,nsecs); return 0; } thanks -john