From owner-svn-src-all@FreeBSD.ORG Wed Mar 18 10:49:19 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 0210D6AB; Wed, 18 Mar 2015 10:49:19 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D7A492B6; Wed, 18 Mar 2015 10:49:18 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t2IAnIOK096233; Wed, 18 Mar 2015 10:49:18 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t2IAnInG096231; Wed, 18 Mar 2015 10:49:18 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201503181049.t2IAnInG096231@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Wed, 18 Mar 2015 10:49:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r280210 - head/sys/ofed/include/linux X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Mar 2015 10:49:19 -0000 Author: hselasky Date: Wed Mar 18 10:49:17 2015 New Revision: 280210 URL: https://svnweb.freebsd.org/changeset/base/280210 Log: Fix problems about 32-bit ticks wraparound and unsigned long conversion: - The linux compat API layer casts the ticks to unsigned long which might cause problems when the ticks value is negative. - Guard against already expired ticks values, by checking if the passed expiry tick is already elapsed. - While at it avoid referring the address of an inlined function. MFC after: 3 days Sponsored by: Mellanox Technologies Modified: head/sys/ofed/include/linux/linux_compat.c head/sys/ofed/include/linux/timer.h Modified: head/sys/ofed/include/linux/linux_compat.c ============================================================================== --- head/sys/ofed/include/linux/linux_compat.c Wed Mar 18 09:39:31 2015 (r280209) +++ head/sys/ofed/include/linux/linux_compat.c Wed Mar 18 10:49:17 2015 (r280210) @@ -57,6 +57,7 @@ #include #include #include +#include #include @@ -77,6 +78,8 @@ struct list_head pci_devices; struct net init_net; spinlock_t pci_lock; +unsigned long linux_timer_hz_mask; + int panic_cmp(struct rb_node *one, struct rb_node *two) { @@ -724,6 +727,60 @@ kasprintf(gfp_t gfp, const char *fmt, .. return p; } +static int +linux_timer_jiffies_until(unsigned long expires) +{ + int delta = expires - jiffies; + /* guard against already expired values */ + if (delta < 1) + delta = 1; + return (delta); +} + +static void +linux_timer_callback_wrapper(void *context) +{ + struct timer_list *timer; + + timer = context; + timer->function(timer->data); +} + +void +mod_timer(struct timer_list *timer, unsigned long expires) +{ + + timer->expires = expires; + callout_reset(&timer->timer_callout, + linux_timer_jiffies_until(expires), + &linux_timer_callback_wrapper, timer); +} + +void +add_timer(struct timer_list *timer) +{ + + callout_reset(&timer->timer_callout, + linux_timer_jiffies_until(timer->expires), + &linux_timer_callback_wrapper, timer); +} + +static void +linux_timer_init(void *arg) +{ + + /* + * Compute an internal HZ value which can divide 2**32 to + * avoid timer rounding problems when the tick value wraps + * around 2**32: + */ + linux_timer_hz_mask = 1; + while (linux_timer_hz_mask < (unsigned long)hz) + linux_timer_hz_mask *= 2; + linux_timer_hz_mask--; +} +SYSINIT(linux_timer, SI_SUB_DRIVERS, SI_ORDER_FIRST, linux_timer_init, NULL); + static void linux_compat_init(void) { Modified: head/sys/ofed/include/linux/timer.h ============================================================================== --- head/sys/ofed/include/linux/timer.h Wed Mar 18 09:39:31 2015 (r280209) +++ head/sys/ofed/include/linux/timer.h Wed Mar 18 10:49:17 2015 (r280210) @@ -27,7 +27,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _LINUX_TIMER_H_ -#define _LINUX_TIMER_H_ +#define _LINUX_TIMER_H_ #include @@ -36,20 +36,13 @@ #include struct timer_list { - struct callout timer_callout; - void (*function)(unsigned long); - unsigned long data; - unsigned long expires; + struct callout timer_callout; + void (*function) (unsigned long); + unsigned long data; + unsigned long expires; }; -static inline void -_timer_fn(void *context) -{ - struct timer_list *timer; - - timer = context; - timer->function(timer->data); -} +extern unsigned long linux_timer_hz_mask; #define setup_timer(timer, func, dat) \ do { \ @@ -65,28 +58,15 @@ do { \ callout_init(&(timer)->timer_callout, CALLOUT_MPSAFE); \ } while (0) -#define mod_timer(timer, exp) \ -do { \ - (timer)->expires = (exp); \ - callout_reset(&(timer)->timer_callout, (exp) - jiffies, \ - _timer_fn, (timer)); \ -} while (0) - -#define add_timer(timer) \ - callout_reset(&(timer)->timer_callout, \ - (timer)->expires - jiffies, _timer_fn, (timer)) +extern void mod_timer(struct timer_list *, unsigned long); +extern void add_timer(struct timer_list *); #define del_timer(timer) callout_stop(&(timer)->timer_callout) #define del_timer_sync(timer) callout_drain(&(timer)->timer_callout) - #define timer_pending(timer) callout_pending(&(timer)->timer_callout) +#define round_jiffies(j) \ + ((unsigned long)(((j) + linux_timer_hz_mask) & ~linux_timer_hz_mask)) +#define round_jiffies_relative(j) \ + round_jiffies(j) -static inline unsigned long -round_jiffies(unsigned long j) -{ - return roundup(j, hz); -} - -#define round_jiffies_relative(j) round_jiffies(j) - -#endif /* _LINUX_TIMER_H_ */ +#endif /* _LINUX_TIMER_H_ */