mirror of
https://github.com/opnsense/src.git
synced 2026-06-13 02:30:51 -04:00
linuxkpi: Introduce a properly typed jiffies
Now that we have a long-sized tick counter, we can migrate to using properly typed timeout parameters in various bits of the LinuxKPI. This fixes a subtle incompatibility that is otherwise difficult to paper over and leads to bugs when ticks values are sign-extended. - Introduce a "jiffies" symbol in subr_ticks.S, declared only in the LinuxKPI as an unsigned long. - Remove all references to "ticks" from the LinuxKPI. - Convert interfaces to match Linux's type signatures where it makes sense. Reviewed by: manu Tested by: bz Differential Revision: https://reviews.freebsd.org/D48523
This commit is contained in:
parent
4fa275a5f3
commit
325aa4dbd1
13 changed files with 68 additions and 60 deletions
|
|
@ -60,7 +60,8 @@ struct completion {
|
|||
|
||||
extern void linux_complete_common(struct completion *, int);
|
||||
extern int linux_wait_for_common(struct completion *, int);
|
||||
extern int linux_wait_for_timeout_common(struct completion *, int, int);
|
||||
extern unsigned long linux_wait_for_timeout_common(struct completion *,
|
||||
unsigned long, int);
|
||||
extern int linux_try_wait_for_completion(struct completion *);
|
||||
extern int linux_completion_done(struct completion *);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,21 +32,21 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/limits.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define jiffies ticks
|
||||
#define jiffies_64 ticks
|
||||
extern unsigned long jiffies; /* defined in sys/kern/subr_ticks.S */
|
||||
#define jiffies_64 jiffies /* XXX-MJ wrong on 32-bit platforms */
|
||||
#define jiffies_to_msecs(x) ((unsigned int)(((int64_t)(int)(x)) * 1000 / hz))
|
||||
|
||||
#define MAX_JIFFY_OFFSET ((INT_MAX >> 1) - 1)
|
||||
#define MAX_JIFFY_OFFSET ((LONG_MAX >> 1) - 1)
|
||||
|
||||
#define time_after(a, b) ((int)((b) - (a)) < 0)
|
||||
#define time_after(a, b) ((long)((b) - (a)) < 0)
|
||||
#define time_after32(a, b) ((int32_t)((uint32_t)(b) - (uint32_t)(a)) < 0)
|
||||
#define time_before(a, b) time_after(b,a)
|
||||
#define time_before32(a, b) time_after32(b, a)
|
||||
#define time_after_eq(a, b) ((int)((a) - (b)) >= 0)
|
||||
#define time_after_eq(a, b) ((long)((a) - (b)) >= 0)
|
||||
#define time_before_eq(a, b) time_after_eq(b, a)
|
||||
#define time_in_range(a,b,c) \
|
||||
(time_after_eq(a,b) && time_before_eq(a,c))
|
||||
|
|
@ -68,7 +68,7 @@ extern uint64_t lkpi_msec2hz_rem;
|
|||
extern uint64_t lkpi_msec2hz_div;
|
||||
extern uint64_t lkpi_msec2hz_max;
|
||||
|
||||
static inline int
|
||||
static inline unsigned long
|
||||
msecs_to_jiffies(uint64_t msec)
|
||||
{
|
||||
uint64_t result;
|
||||
|
|
@ -79,10 +79,10 @@ msecs_to_jiffies(uint64_t msec)
|
|||
if (result > MAX_JIFFY_OFFSET)
|
||||
result = MAX_JIFFY_OFFSET;
|
||||
|
||||
return ((int)result);
|
||||
return ((unsigned long)result);
|
||||
}
|
||||
|
||||
static inline int
|
||||
static inline unsigned long
|
||||
usecs_to_jiffies(uint64_t usec)
|
||||
{
|
||||
uint64_t result;
|
||||
|
|
@ -93,7 +93,7 @@ usecs_to_jiffies(uint64_t usec)
|
|||
if (result > MAX_JIFFY_OFFSET)
|
||||
result = MAX_JIFFY_OFFSET;
|
||||
|
||||
return ((int)result);
|
||||
return ((unsigned long)result);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
|
|
@ -120,32 +120,33 @@ nsecs_to_jiffies(uint64_t nsec)
|
|||
}
|
||||
|
||||
static inline uint64_t
|
||||
jiffies_to_nsecs(int j)
|
||||
jiffies_to_nsecs(unsigned long j)
|
||||
{
|
||||
|
||||
return ((1000000000ULL / hz) * (uint64_t)(unsigned int)j);
|
||||
return ((1000000000ULL / hz) * (uint64_t)j);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
jiffies_to_usecs(int j)
|
||||
jiffies_to_usecs(unsigned long j)
|
||||
{
|
||||
|
||||
return ((1000000ULL / hz) * (uint64_t)(unsigned int)j);
|
||||
return ((1000000ULL / hz) * (uint64_t)j);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
get_jiffies_64(void)
|
||||
{
|
||||
|
||||
return ((uint64_t)(unsigned int)ticks);
|
||||
return ((uint64_t)jiffies);
|
||||
}
|
||||
|
||||
static inline int
|
||||
linux_timer_jiffies_until(int expires)
|
||||
static inline unsigned long
|
||||
linux_timer_jiffies_until(unsigned long expires)
|
||||
{
|
||||
int delta = expires - jiffies;
|
||||
unsigned long delta = expires - jiffies;
|
||||
|
||||
/* guard against already expired values */
|
||||
if (delta < 1)
|
||||
if ((long)delta < 1)
|
||||
delta = 1;
|
||||
return (delta);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
|
||||
#include <asm/atomic.h>
|
||||
|
||||
#define MAX_SCHEDULE_TIMEOUT INT_MAX
|
||||
#define MAX_SCHEDULE_TIMEOUT LONG_MAX
|
||||
|
||||
#define TASK_RUNNING 0x0000
|
||||
#define TASK_INTERRUPTIBLE 0x0001
|
||||
|
|
@ -160,7 +160,7 @@ void linux_send_sig(int signo, struct task_struct *task);
|
|||
linux_send_sig(signo, task); \
|
||||
} while (0)
|
||||
|
||||
int linux_schedule_timeout(int timeout);
|
||||
long linux_schedule_timeout(long timeout);
|
||||
|
||||
static inline void
|
||||
linux_schedule_save_interrupt_value(struct task_struct *task, int value)
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ struct timer_list {
|
|||
void (*function_415) (struct timer_list *);
|
||||
};
|
||||
unsigned long data;
|
||||
int expires;
|
||||
unsigned long expires;
|
||||
};
|
||||
|
||||
extern unsigned long linux_timer_hz_mask;
|
||||
|
|
@ -76,7 +76,7 @@ extern unsigned long linux_timer_hz_mask;
|
|||
callout_init(&(timer)->callout, 1); \
|
||||
} while (0)
|
||||
|
||||
extern int mod_timer(struct timer_list *, int);
|
||||
extern int mod_timer(struct timer_list *, unsigned long);
|
||||
extern void add_timer(struct timer_list *);
|
||||
extern void add_timer_on(struct timer_list *, int cpu);
|
||||
extern int del_timer(struct timer_list *);
|
||||
|
|
@ -86,7 +86,7 @@ extern int timer_shutdown_sync(struct timer_list *);
|
|||
|
||||
#define timer_pending(timer) callout_pending(&(timer)->callout)
|
||||
#define round_jiffies(j) \
|
||||
((int)(((j) + linux_timer_hz_mask) & ~linux_timer_hz_mask))
|
||||
((unsigned long)(((j) + linux_timer_hz_mask) & ~linux_timer_hz_mask))
|
||||
#define round_jiffies_relative(j) round_jiffies(j)
|
||||
#define round_jiffies_up(j) round_jiffies(j)
|
||||
#define round_jiffies_up_relative(j) round_jiffies_up(j)
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ void linux_wake_up(wait_queue_head_t *, unsigned int, int, bool);
|
|||
#define wake_up_interruptible_all(wqh) \
|
||||
linux_wake_up(wqh, TASK_INTERRUPTIBLE, 0, false)
|
||||
|
||||
int linux_wait_event_common(wait_queue_head_t *, wait_queue_t *, int,
|
||||
int linux_wait_event_common(wait_queue_head_t *, wait_queue_t *, long,
|
||||
unsigned int, spinlock_t *);
|
||||
|
||||
/*
|
||||
|
|
@ -148,9 +148,9 @@ int linux_wait_event_common(wait_queue_head_t *, wait_queue_t *, int,
|
|||
*/
|
||||
#define __wait_event_common(wqh, cond, timeout, state, lock) ({ \
|
||||
DEFINE_WAIT(__wq); \
|
||||
const int __timeout = ((int)(timeout)) < 1 ? 1 : (timeout); \
|
||||
int __start = ticks; \
|
||||
int __ret = 0; \
|
||||
const long __timeout = ((long)(timeout)) < 1 ? 1 : (timeout); \
|
||||
long __start = jiffies; \
|
||||
long __ret = 0; \
|
||||
\
|
||||
for (;;) { \
|
||||
linux_prepare_to_wait(&(wqh), &__wq, state); \
|
||||
|
|
@ -166,7 +166,7 @@ int linux_wait_event_common(wait_queue_head_t *, wait_queue_t *, int,
|
|||
if (__ret == -EWOULDBLOCK) \
|
||||
__ret = !!(cond); \
|
||||
else if (__ret != -ERESTARTSYS) { \
|
||||
__ret = __timeout + __start - ticks; \
|
||||
__ret = __timeout + __start - jiffies; \
|
||||
/* range check return value */ \
|
||||
if (__ret < 1) \
|
||||
__ret = 1; \
|
||||
|
|
@ -284,7 +284,7 @@ void linux_finish_wait(wait_queue_head_t *, wait_queue_t *);
|
|||
#define finish_wait(wqh, wq) linux_finish_wait(wqh, wq)
|
||||
|
||||
void linux_wake_up_bit(void *, int);
|
||||
int linux_wait_on_bit_timeout(unsigned long *, int, unsigned int, int);
|
||||
int linux_wait_on_bit_timeout(unsigned long *, int, unsigned int, long);
|
||||
void linux_wake_up_atomic_t(atomic_t *);
|
||||
int linux_wait_on_atomic_t(atomic_t *, unsigned int);
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ struct delayed_work {
|
|||
struct {
|
||||
struct callout callout;
|
||||
struct mtx mtx;
|
||||
int expires;
|
||||
long expires;
|
||||
} timer;
|
||||
};
|
||||
|
||||
|
|
@ -245,7 +245,7 @@ extern struct workqueue_struct *linux_create_workqueue_common(const char *, int)
|
|||
extern void linux_destroy_workqueue(struct workqueue_struct *);
|
||||
extern bool linux_queue_work_on(int cpu, struct workqueue_struct *, struct work_struct *);
|
||||
extern bool linux_queue_delayed_work_on(int cpu, struct workqueue_struct *,
|
||||
struct delayed_work *, unsigned delay);
|
||||
struct delayed_work *, unsigned long delay);
|
||||
extern bool linux_cancel_work(struct work_struct *);
|
||||
extern bool linux_cancel_delayed_work(struct delayed_work *);
|
||||
extern bool linux_cancel_work_sync(struct work_struct *);
|
||||
|
|
|
|||
|
|
@ -5091,11 +5091,11 @@ lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m)
|
|||
skb_queue_tail(<xq->skbq, skb);
|
||||
#ifdef LINUXKPI_DEBUG_80211
|
||||
if (linuxkpi_debug_80211 & D80211_TRACE_TX)
|
||||
printf("%s:%d mo_wake_tx_queue :: %d %u lsta %p sta %p "
|
||||
printf("%s:%d mo_wake_tx_queue :: %d %lu lsta %p sta %p "
|
||||
"ni %p %6D skb %p lxtq %p { qlen %u, ac %d tid %u } "
|
||||
"WAKE_TX_Q ac %d prio %u qmap %u\n",
|
||||
__func__, __LINE__,
|
||||
curthread->td_tid, (unsigned int)ticks,
|
||||
curthread->td_tid, jiffies,
|
||||
lsta, sta, ni, ni->ni_macaddr, ":", skb, ltxq,
|
||||
skb_queue_len(<xq->skbq), ltxq->txq.ac,
|
||||
ltxq->txq.tid, ac, skb->priority, skb->qmap);
|
||||
|
|
|
|||
|
|
@ -40,9 +40,9 @@
|
|||
#ifdef LINUXKPI_DEBUG_80211
|
||||
#define LKPI_80211_TRACE_MO(fmt, ...) \
|
||||
if (linuxkpi_debug_80211 & D80211_TRACE_MO) \
|
||||
printf("LKPI_80211_TRACE_MO %s:%d: %d %d %u_" fmt "\n", \
|
||||
printf("LKPI_80211_TRACE_MO %s:%d: %d %d %lu_" fmt "\n", \
|
||||
__func__, __LINE__, curcpu, curthread->td_tid, \
|
||||
(unsigned int)ticks, __VA_ARGS__)
|
||||
jiffies, __VA_ARGS__)
|
||||
#else
|
||||
#define LKPI_80211_TRACE_MO(...) do { } while(0)
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2072,7 +2072,7 @@ linux_timer_callback_wrapper(void *context)
|
|||
}
|
||||
|
||||
int
|
||||
mod_timer(struct timer_list *timer, int expires)
|
||||
mod_timer(struct timer_list *timer, unsigned long expires)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
|
@ -2268,12 +2268,12 @@ intr:
|
|||
/*
|
||||
* Time limited wait for done != 0 with or without signals.
|
||||
*/
|
||||
int
|
||||
linux_wait_for_timeout_common(struct completion *c, int timeout, int flags)
|
||||
unsigned long
|
||||
linux_wait_for_timeout_common(struct completion *c, unsigned long timeout,
|
||||
int flags)
|
||||
{
|
||||
struct task_struct *task;
|
||||
int end = jiffies + timeout;
|
||||
int error;
|
||||
unsigned long end = jiffies + timeout, error;
|
||||
|
||||
if (SCHEDULER_STOPPED())
|
||||
return (0);
|
||||
|
|
|
|||
|
|
@ -63,22 +63,22 @@ SYSCTL_INT(_compat_linuxkpi, OID_AUTO, debug_napi, CTLFLAG_RWTUN,
|
|||
#define DNAPI_DIRECT_DISPATCH 0x1000
|
||||
|
||||
#define NAPI_TRACE(_n) if (debug_napi & DNAPI_TRACE) \
|
||||
printf("NAPI_TRACE %s:%d %u %p (%#jx %b)\n", __func__, __LINE__, \
|
||||
(unsigned int)ticks, _n, (uintmax_t)(_n)->state, \
|
||||
printf("NAPI_TRACE %s:%d %lu %p (%#jx %b)\n", __func__, __LINE__, \
|
||||
jiffies, _n, (uintmax_t)(_n)->state, \
|
||||
(int)(_n)->state, LKPI_NAPI_FLAGS)
|
||||
#define NAPI_TRACE2D(_n, _d) if (debug_napi & DNAPI_TRACE) \
|
||||
printf("NAPI_TRACE %s:%d %u %p (%#jx %b) %d\n", __func__, __LINE__, \
|
||||
(unsigned int)ticks, _n, (uintmax_t)(_n)->state, \
|
||||
printf("NAPI_TRACE %s:%d %lu %p (%#jx %b) %d\n", __func__, __LINE__, \
|
||||
jiffies, _n, (uintmax_t)(_n)->state, \
|
||||
(int)(_n)->state, LKPI_NAPI_FLAGS, _d)
|
||||
#define NAPI_TRACE_TASK(_n, _p, _c) if (debug_napi & DNAPI_TRACE_TASK) \
|
||||
printf("NAPI_TRACE %s:%d %u %p (%#jx %b) pending %d count %d " \
|
||||
printf("NAPI_TRACE %s:%d %lu %p (%#jx %b) pending %d count %d " \
|
||||
"rx_count %d\n", __func__, __LINE__, \
|
||||
(unsigned int)ticks, _n, (uintmax_t)(_n)->state, \
|
||||
jiffies, _n, (uintmax_t)(_n)->state, \
|
||||
(int)(_n)->state, LKPI_NAPI_FLAGS, _p, _c, (_n)->rx_count)
|
||||
#define NAPI_TODO() if (debug_napi & DNAPI_TODO) \
|
||||
printf("NAPI_TODO %s:%d %d\n", __func__, __LINE__, ticks)
|
||||
printf("NAPI_TODO %s:%d %lu\n", __func__, __LINE__, jiffies)
|
||||
#define NAPI_IMPROVE() if (debug_napi & DNAPI_IMPROVE) \
|
||||
printf("NAPI_IMPROVE %s:%d %d\n", __func__, __LINE__, ticks)
|
||||
printf("NAPI_IMPROVE %s:%d %lu\n", __func__, __LINE__, jiffies)
|
||||
|
||||
#define NAPI_DIRECT_DISPATCH() ((debug_napi & DNAPI_DIRECT_DISPATCH) != 0)
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
static int
|
||||
linux_add_to_sleepqueue(void *wchan, struct task_struct *task,
|
||||
const char *wmesg, int timeout, int state)
|
||||
const char *wmesg, long timeout, int state)
|
||||
{
|
||||
int flags, ret;
|
||||
|
||||
|
|
@ -249,7 +249,7 @@ linux_waitqueue_active(wait_queue_head_t *wqh)
|
|||
}
|
||||
|
||||
int
|
||||
linux_wait_event_common(wait_queue_head_t *wqh, wait_queue_t *wq, int timeout,
|
||||
linux_wait_event_common(wait_queue_head_t *wqh, wait_queue_t *wq, long timeout,
|
||||
unsigned int state, spinlock_t *lock)
|
||||
{
|
||||
struct task_struct *task;
|
||||
|
|
@ -280,13 +280,13 @@ linux_wait_event_common(wait_queue_head_t *wqh, wait_queue_t *wq, int timeout,
|
|||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
linux_schedule_timeout(int timeout)
|
||||
long
|
||||
linux_schedule_timeout(long timeout)
|
||||
{
|
||||
struct task_struct *task;
|
||||
long remainder;
|
||||
int ret;
|
||||
int state;
|
||||
int remainder;
|
||||
|
||||
task = current;
|
||||
|
||||
|
|
@ -296,7 +296,7 @@ linux_schedule_timeout(int timeout)
|
|||
else if (timeout == MAX_SCHEDULE_TIMEOUT)
|
||||
timeout = 0;
|
||||
|
||||
remainder = ticks + timeout;
|
||||
remainder = jiffies + timeout;
|
||||
|
||||
sleepq_lock(task);
|
||||
state = atomic_read(&task->state);
|
||||
|
|
@ -313,7 +313,7 @@ linux_schedule_timeout(int timeout)
|
|||
return (MAX_SCHEDULE_TIMEOUT);
|
||||
|
||||
/* range check return value */
|
||||
remainder -= ticks;
|
||||
remainder -= jiffies;
|
||||
|
||||
/* range check return value */
|
||||
if (ret == -ERESTARTSYS && remainder < 1)
|
||||
|
|
@ -344,7 +344,7 @@ linux_wake_up_bit(void *word, int bit)
|
|||
|
||||
int
|
||||
linux_wait_on_bit_timeout(unsigned long *word, int bit, unsigned int state,
|
||||
int timeout)
|
||||
long timeout)
|
||||
{
|
||||
struct task_struct *task;
|
||||
void *wchan;
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ linux_flush_rcu_work(struct rcu_work *rwork)
|
|||
*/
|
||||
bool
|
||||
linux_queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
|
||||
struct delayed_work *dwork, unsigned delay)
|
||||
struct delayed_work *dwork, unsigned long delay)
|
||||
{
|
||||
static const uint8_t states[WORK_ST_MAX] __aligned(8) = {
|
||||
[WORK_ST_IDLE] = WORK_ST_TIMER, /* start timeout */
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
|
||||
/*
|
||||
* Define the "ticks" and "ticksl" variables. The former is overlaid onto the
|
||||
* low bits of the latter.
|
||||
* low bits of the latter. Also define an alias "jiffies" of "ticksl",
|
||||
* used by the LinuxKPI.
|
||||
*/
|
||||
|
||||
#if defined(__aarch64__)
|
||||
|
|
@ -34,3 +35,8 @@ ticksl: .zero __SIZEOF_LONG__
|
|||
.type ticks, %object
|
||||
ticks =ticksl + TICKS_OFFSET
|
||||
.size ticks, __SIZEOF_INT__
|
||||
|
||||
.global jiffies
|
||||
.type jiffies, %object
|
||||
jiffies = ticksl
|
||||
.size jiffies, __SIZEOF_LONG__
|
||||
|
|
|
|||
Loading…
Reference in a new issue