xpp: Convert struct timeval -> ktime_t.

`struct timeval` has been removed from the kernel interface in 5.0 as
part of fixing the 2038 problem. ktime_t is the preferred kernel time
interface now.

Signed-off-by: Shaun Ruffell <sruffell@sruffell.net>
This commit is contained in:
Shaun Ruffell 2019-03-27 17:17:45 +00:00
parent 8468250328
commit ffcd08205c
10 changed files with 112 additions and 139 deletions

View File

@ -188,7 +188,7 @@ struct FXS_priv_data {
xpp_line_t neon_blinking; xpp_line_t neon_blinking;
xpp_line_t neonstate; xpp_line_t neonstate;
xpp_line_t vbat_h; /* High voltage */ xpp_line_t vbat_h; /* High voltage */
struct timeval prev_key_time[CHANNELS_PERXPD]; ktime_t prev_key_time[CHANNELS_PERXPD];
int led_counter[NUM_LEDS][CHANNELS_PERXPD]; int led_counter[NUM_LEDS][CHANNELS_PERXPD];
int overheat_reset_counter[CHANNELS_PERXPD]; int overheat_reset_counter[CHANNELS_PERXPD];
int ohttimer[CHANNELS_PERXPD]; int ohttimer[CHANNELS_PERXPD];
@ -1681,8 +1681,7 @@ static void process_hookstate(xpd_t *xpd, xpp_line_t offhook,
* Reset our previous DTMF memories... * Reset our previous DTMF memories...
*/ */
BIT_CLR(priv->prev_key_down, i); BIT_CLR(priv->prev_key_down, i);
priv->prev_key_time[i].tv_sec = priv->prev_key_time[i] = ktime_set(0L, 0UL);
priv->prev_key_time[i].tv_usec = 0L;
if (IS_SET(offhook, i)) { if (IS_SET(offhook, i)) {
LINE_DBG(SIGNAL, xpd, i, "OFFHOOK\n"); LINE_DBG(SIGNAL, xpd, i, "OFFHOOK\n");
MARK_ON(priv, i, LED_GREEN); MARK_ON(priv, i, LED_GREEN);
@ -1795,8 +1794,9 @@ static void process_dtmf(xpd_t *xpd, uint portnum, __u8 val)
bool want_mute; bool want_mute;
bool want_event; bool want_event;
struct FXS_priv_data *priv; struct FXS_priv_data *priv;
struct timeval now; ktime_t now;
int msec = 0; s64 msec = 0;
struct timespec64 ts;
if (!dtmf_detection) if (!dtmf_detection)
return; return;
@ -1813,16 +1813,16 @@ static void process_dtmf(xpd_t *xpd, uint portnum, __u8 val)
BIT_SET(priv->prev_key_down, portnum); BIT_SET(priv->prev_key_down, portnum);
else else
BIT_CLR(priv->prev_key_down, portnum); BIT_CLR(priv->prev_key_down, portnum);
do_gettimeofday(&now); now = ktime_get();
if (priv->prev_key_time[portnum].tv_sec != 0) if (!dahdi_ktime_equal(priv->prev_key_time[portnum], ktime_set(0, 0)))
msec = usec_diff(&now, &priv->prev_key_time[portnum]) / 1000; msec = ktime_ms_delta(now, priv->prev_key_time[portnum]);
priv->prev_key_time[portnum] = now; priv->prev_key_time[portnum] = now;
ts = ktime_to_timespec64(now);
LINE_DBG(SIGNAL, xpd, portnum, LINE_DBG(SIGNAL, xpd, portnum,
"[%lu.%06lu] DTMF digit %-4s '%c' " "[%lld.%06ld] DTMF digit %-4s '%c' (val=%d, want_mute=%s want_event=%s, delta=%lld msec)\n",
"(val=%d, want_mute=%s want_event=%s, delta=%d msec)\n", (s64)ts.tv_sec, ts.tv_nsec * NSEC_PER_USEC,
now.tv_sec, now.tv_usec, (key_down) ? "DOWN" : "UP", digit, (key_down) ? "DOWN" : "UP", digit, val,
val, (want_mute) ? "yes" : "no", (want_event) ? "yes" : "no", (want_mute) ? "yes" : "no", (want_event) ? "yes" : "no", msec);
msec);
/* /*
* FIXME: we currently don't use the want_dtmf_mute until * FIXME: we currently don't use the want_dtmf_mute until
* we are sure about the logic in Asterisk native bridging. * we are sure about the logic in Asterisk native bridging.

View File

@ -259,7 +259,7 @@ void xframe_init(xbus_t *xbus, xframe_t *xframe, void *buf, size_t maxsize,
xframe->packets = xframe->first_free = buf; xframe->packets = xframe->first_free = buf;
xframe->frame_maxlen = maxsize; xframe->frame_maxlen = maxsize;
atomic_set(&xframe->frame_len, 0); atomic_set(&xframe->frame_len, 0);
do_gettimeofday(&xframe->tv_created); xframe->kt_created = ktime_get();
xframe->xframe_magic = XFRAME_MAGIC; xframe->xframe_magic = XFRAME_MAGIC;
} }
EXPORT_SYMBOL(xframe_init); EXPORT_SYMBOL(xframe_init);
@ -946,12 +946,12 @@ static int xbus_initialize(xbus_t *xbus)
int unit; int unit;
int subunit; int subunit;
xpd_t *xpd; xpd_t *xpd;
struct timeval time_start; ktime_t time_start;
struct timeval time_end; ktime_t time_end;
unsigned long timediff; unsigned long timediff;
int res = 0; int res = 0;
do_gettimeofday(&time_start); time_start = ktime_get();
XBUS_DBG(DEVICES, xbus, "refcount_xbus=%d\n", refcount_xbus(xbus)); XBUS_DBG(DEVICES, xbus, "refcount_xbus=%d\n", refcount_xbus(xbus));
if (xbus_aquire_xpds(xbus) < 0) /* Until end of initialization */ if (xbus_aquire_xpds(xbus) < 0) /* Until end of initialization */
return -EBUSY; return -EBUSY;
@ -989,7 +989,7 @@ static int xbus_initialize(xbus_t *xbus)
} }
} }
xbus_echocancel(xbus, 1); xbus_echocancel(xbus, 1);
do_gettimeofday(&time_end); time_end = ktime_get();
timediff = usec_diff(&time_end, &time_start); timediff = usec_diff(&time_end, &time_start);
timediff /= 1000 * 100; timediff /= 1000 * 100;
XBUS_INFO(xbus, "Initialized in %ld.%1ld sec\n", timediff / 10, XBUS_INFO(xbus, "Initialized in %ld.%1ld sec\n", timediff / 10,
@ -1755,8 +1755,7 @@ out:
static void xbus_fill_proc_queue(struct seq_file *sfile, struct xframe_queue *q) static void xbus_fill_proc_queue(struct seq_file *sfile, struct xframe_queue *q)
{ {
seq_printf(sfile, seq_printf(sfile,
"%-15s: counts %3d, %3d, %3d worst %3d, overflows %3d " "%-15s: counts %3d, %3d, %3d worst %3d, overflows %3d worst_lag %02lld.%lld ms\n",
"worst_lag %02ld.%ld ms\n",
q->name, q->steady_state_count, q->count, q->max_count, q->name, q->steady_state_count, q->count, q->max_count,
q->worst_count, q->overflows, q->worst_lag_usec / 1000, q->worst_count, q->overflows, q->worst_lag_usec / 1000,
q->worst_lag_usec % 1000); q->worst_lag_usec % 1000);
@ -1792,8 +1791,9 @@ static int xbus_proc_show(struct seq_file *sfile, void *data)
seq_printf(sfile, "%5d ", xbus->cpu_rcv_tasklet[i]); seq_printf(sfile, "%5d ", xbus->cpu_rcv_tasklet[i]);
seq_printf(sfile, "\n"); seq_printf(sfile, "\n");
} }
seq_printf(sfile, "self_ticking: %d (last_tick at %ld)\n", seq_printf(sfile, "self_ticking: %d (last_tick at %lld)\n",
xbus->self_ticking, xbus->ticker.last_sample.tv.tv_sec); xbus->self_ticking, ktime_divns(xbus->ticker.last_sample,
NSEC_PER_SEC));
seq_printf(sfile, "command_tick: %d\n", seq_printf(sfile, "command_tick: %d\n",
xbus->command_tick_counter); xbus->command_tick_counter);
seq_printf(sfile, "usec_nosend: %d\n", xbus->usec_nosend); seq_printf(sfile, "usec_nosend: %d\n", xbus->usec_nosend);

View File

@ -234,8 +234,8 @@ struct xbus {
spinlock_t lock; spinlock_t lock;
/* PCM metrics */ /* PCM metrics */
struct timeval last_tx_sync; ktime_t last_tx_sync;
struct timeval last_rx_sync; ktime_t last_rx_sync;
unsigned long max_tx_sync; unsigned long max_tx_sync;
unsigned long min_tx_sync; unsigned long min_tx_sync;
unsigned long max_rx_sync; unsigned long max_rx_sync;
@ -255,7 +255,7 @@ struct xbus {
*/ */
int sync_adjustment; int sync_adjustment;
int sync_adjustment_offset; int sync_adjustment_offset;
long pll_updated_at; ktime_t pll_updated_at;
atomic_t num_xpds; atomic_t num_xpds;
@ -279,10 +279,10 @@ struct xframe {
struct list_head frame_list; struct list_head frame_list;
atomic_t frame_len; atomic_t frame_len;
xbus_t *xbus; xbus_t *xbus;
struct timeval tv_created; ktime_t kt_created;
struct timeval tv_queued; ktime_t kt_queued;
struct timeval tv_submitted; ktime_t kt_submitted;
struct timeval tv_received; ktime_t kt_received;
/* filled by transport layer */ /* filled by transport layer */
size_t frame_maxlen; size_t frame_maxlen;
__u8 *packets; /* max XFRAME_DATASIZE */ __u8 *packets; /* max XFRAME_DATASIZE */
@ -358,4 +358,9 @@ void xbus_sysfs_remove(xbus_t *xbus);
void astribank_uevent_send(xbus_t *xbus, enum kobject_action act); void astribank_uevent_send(xbus_t *xbus, enum kobject_action act);
static inline s64 xpp_ktime_sec_delta(ktime_t later, ktime_t earlier)
{
return ktime_divns(ktime_sub(later, earlier), NSEC_PER_SEC);
}
#endif /* XBUS_CORE_H */ #endif /* XBUS_CORE_H */

View File

@ -111,24 +111,23 @@ static void xpp_ticker_init(struct xpp_ticker *ticker)
{ {
memset(ticker, 0, sizeof(*ticker)); memset(ticker, 0, sizeof(*ticker));
spin_lock_init(&ticker->lock); spin_lock_init(&ticker->lock);
do_gettimeofday(&ticker->last_sample.tv); ticker->last_sample = ktime_get();
ticker->first_sample = ticker->last_sample; ticker->first_sample = ticker->last_sample;
ticker_set_cycle(ticker, SYNC_ADJ_QUICK); ticker_set_cycle(ticker, SYNC_ADJ_QUICK);
} }
static int xpp_ticker_step(struct xpp_ticker *ticker, const struct timeval *t) static int xpp_ticker_step(struct xpp_ticker *ticker, const ktime_t t)
{ {
unsigned long flags; unsigned long flags;
long usec; s64 usec;
bool cycled = 0; bool cycled = 0;
spin_lock_irqsave(&ticker->lock, flags); spin_lock_irqsave(&ticker->lock, flags);
ticker->last_sample.tv = *t; ticker->last_sample = t;
/* rate adjust */ /* rate adjust */
if ((ticker->count % ticker->cycle) == ticker->cycle - 1) { if ((ticker->count % ticker->cycle) == ticker->cycle - 1) {
usec = usec = ktime_us_delta(ticker->last_sample,
(long)usec_diff(&ticker->last_sample.tv, ticker->first_sample);
&ticker->first_sample.tv);
ticker->first_sample = ticker->last_sample; ticker->first_sample = ticker->last_sample;
ticker->tick_period = usec / ticker->cycle; ticker->tick_period = usec / ticker->cycle;
cycled = 1; cycled = 1;
@ -147,7 +146,7 @@ static inline void xbus_drift_clear(xbus_t *xbus)
{ {
struct xpp_drift *di = &xbus->drift; struct xpp_drift *di = &xbus->drift;
do_gettimeofday(&di->last_lost_tick.tv); di->last_lost_tick = ktime_get();
ticker_set_cycle(&xbus->ticker, SYNC_ADJ_QUICK); ticker_set_cycle(&xbus->ticker, SYNC_ADJ_QUICK);
di->max_speed = -SYNC_ADJ_MAX; di->max_speed = -SYNC_ADJ_MAX;
di->min_speed = SYNC_ADJ_MAX; di->min_speed = SYNC_ADJ_MAX;
@ -190,14 +189,14 @@ static void sample_tick(xbus_t *xbus, int sample)
* including abrupt changes in sync -- to verify the stability of the * including abrupt changes in sync -- to verify the stability of the
* algorithm. * algorithm.
*/ */
static void xpp_drift_step(xbus_t *xbus, const struct timeval *tv) static void xpp_drift_step(xbus_t *xbus, const ktime_t kt)
{ {
struct xpp_drift *di = &xbus->drift; struct xpp_drift *di = &xbus->drift;
struct xpp_ticker *ticker = &xbus->ticker; struct xpp_ticker *ticker = &xbus->ticker;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&di->lock, flags); spin_lock_irqsave(&di->lock, flags);
xpp_ticker_step(&xbus->ticker, tv); xpp_ticker_step(&xbus->ticker, kt);
/* /*
* Do we need to be synchronized and is there an established reference * Do we need to be synchronized and is there an established reference
* ticker (another Astribank or another DAHDI device) already? * ticker (another Astribank or another DAHDI device) already?
@ -206,7 +205,7 @@ static void xpp_drift_step(xbus_t *xbus, const struct timeval *tv)
&& xbus->sync_mode == SYNC_MODE_PLL) { && xbus->sync_mode == SYNC_MODE_PLL) {
int new_delta_tick = ticker->count - ref_ticker->count; int new_delta_tick = ticker->count - ref_ticker->count;
int lost_ticks = new_delta_tick - di->delta_tick; int lost_ticks = new_delta_tick - di->delta_tick;
long usec_delta; s64 usec_delta;
di->delta_tick = new_delta_tick; di->delta_tick = new_delta_tick;
if (lost_ticks) { if (lost_ticks) {
@ -233,9 +232,8 @@ static void xpp_drift_step(xbus_t *xbus, const struct timeval *tv)
} }
} else { } else {
/* Sample a delta */ /* Sample a delta */
usec_delta = usec_delta = ktime_us_delta(ticker->last_sample,
(long)usec_diff(&ticker->last_sample.tv, ref_ticker->last_sample);
&ref_ticker->last_sample.tv);
sample_tick(xbus, usec_delta); sample_tick(xbus, usec_delta);
if ((ticker->count % SYNC_CYCLE) > if ((ticker->count % SYNC_CYCLE) >
(SYNC_CYCLE - SYNC_CYCLE_SAMPLE)) (SYNC_CYCLE - SYNC_CYCLE_SAMPLE))
@ -282,8 +280,7 @@ static void xpp_drift_step(xbus_t *xbus, const struct timeval *tv)
di->offset_min = offset; di->offset_min = offset;
XBUS_DBG(SYNC, xbus, XBUS_DBG(SYNC, xbus,
"offset: %d, min_speed=%d, " "offset: %d, min_speed=%d, max_speed=%d, usec_delta(last)=%lld\n",
"max_speed=%d, usec_delta(last)=%ld\n",
offset_prev, di->min_speed, offset_prev, di->min_speed,
di->max_speed, usec_delta); di->max_speed, usec_delta);
XBUS_DBG(SYNC, xbus, XBUS_DBG(SYNC, xbus,
@ -356,10 +353,8 @@ static void xpp_set_syncer(xbus_t *xbus, bool on)
static void xbus_command_timer(TIMER_DATA_TYPE timer) static void xbus_command_timer(TIMER_DATA_TYPE timer)
{ {
xbus_t *xbus = from_timer(xbus, timer, command_timer); xbus_t *xbus = from_timer(xbus, timer, command_timer);
struct timeval now;
BUG_ON(!xbus); BUG_ON(!xbus);
do_gettimeofday(&now);
xbus_command_queue_tick(xbus); xbus_command_queue_tick(xbus);
if (!xbus->self_ticking) /* Must be 1KHz rate */ if (!xbus->self_ticking) /* Must be 1KHz rate */
mod_timer(&xbus->command_timer, jiffies + 1); mod_timer(&xbus->command_timer, jiffies + 1);
@ -489,34 +484,34 @@ static void reset_sync_counters(void)
static void send_drift(xbus_t *xbus, int drift) static void send_drift(xbus_t *xbus, int drift)
{ {
struct timeval now; const ktime_t now = ktime_get();
const char *msg; const char *msg;
s64 msec_delta;
BUG_ON(abs(drift) > SYNC_ADJ_MAX); BUG_ON(abs(drift) > SYNC_ADJ_MAX);
do_gettimeofday(&now);
if (drift > xbus->sync_adjustment) if (drift > xbus->sync_adjustment)
msg = "up"; msg = "up";
else else
msg = "down"; msg = "down";
msec_delta = ktime_ms_delta(now, xbus->pll_updated_at);
XBUS_DBG(SYNC, xbus, XBUS_DBG(SYNC, xbus,
"%sDRIFT adjust %s (%d) (last update %ld seconds ago)\n", "%sDRIFT adjust %s (%d) (last update %lld seconds ago)\n",
(disable_pll_sync) ? "Fake " : "", msg, drift, (disable_pll_sync) ? "Fake " : "", msg, drift,
now.tv_sec - xbus->pll_updated_at); msec_delta / MSEC_PER_SEC);
if (!disable_pll_sync) if (!disable_pll_sync)
CALL_PROTO(GLOBAL, SYNC_SOURCE, xbus, NULL, SYNC_MODE_PLL, CALL_PROTO(GLOBAL, SYNC_SOURCE, xbus, NULL, SYNC_MODE_PLL,
drift); drift);
xbus->pll_updated_at = now.tv_sec; xbus->pll_updated_at = now;
} }
static void global_tick(void) static void global_tick(void)
{ {
struct timeval now; ktime_t now = ktime_get();
do_gettimeofday(&now);
atomic_inc(&xpp_tick_counter); atomic_inc(&xpp_tick_counter);
if ((atomic_read(&xpp_tick_counter) % BIG_TICK_INTERVAL) == 0) if ((atomic_read(&xpp_tick_counter) % BIG_TICK_INTERVAL) == 0)
reset_sync_counters(); reset_sync_counters();
xpp_ticker_step(&global_ticks_series, &now); xpp_ticker_step(&global_ticks_series, now);
} }
#ifdef DAHDI_SYNC_TICK #ifdef DAHDI_SYNC_TICK
@ -525,11 +520,11 @@ void dahdi_sync_tick(struct dahdi_span *span, int is_master)
struct phonedev *phonedev = container_of(span, struct phonedev, span); struct phonedev *phonedev = container_of(span, struct phonedev, span);
xpd_t *xpd = container_of(phonedev, struct xpd, phonedev); xpd_t *xpd = container_of(phonedev, struct xpd, phonedev);
static int redundant_ticks; /* for extra spans */ static int redundant_ticks; /* for extra spans */
struct timeval now; ktime_t now;
if (!force_dahdi_sync) if (!force_dahdi_sync)
goto noop; goto noop;
do_gettimeofday(&now); now = ktime_get();
BUG_ON(!xpd); BUG_ON(!xpd);
/* /*
* Detect if any of our spans is dahdi sync master * Detect if any of our spans is dahdi sync master
@ -562,7 +557,7 @@ void dahdi_sync_tick(struct dahdi_span *span, int is_master)
#endif #endif
goto noop; goto noop;
} }
xpp_ticker_step(&dahdi_ticker, &now); xpp_ticker_step(&dahdi_ticker, now);
dahdi_tick_count++; dahdi_tick_count++;
//flip_parport_bit(1); //flip_parport_bit(1);
noop: noop:
@ -854,15 +849,14 @@ static bool pcm_valid(xpd_t *xpd, xpacket_t *pack)
static inline void pcm_frame_out(xbus_t *xbus, xframe_t *xframe) static inline void pcm_frame_out(xbus_t *xbus, xframe_t *xframe)
{ {
unsigned long flags; unsigned long flags;
struct timeval now; const ktime_t now = ktime_get();
unsigned long usec; s64 usec;
spin_lock_irqsave(&xbus->lock, flags); spin_lock_irqsave(&xbus->lock, flags);
do_gettimeofday(&now);
if (unlikely(disable_pcm || !XBUS_IS(xbus, READY))) if (unlikely(disable_pcm || !XBUS_IS(xbus, READY)))
goto dropit; goto dropit;
if (XPACKET_ADDR_SYNC((xpacket_t *)xframe->packets)) { if (XPACKET_ADDR_SYNC((xpacket_t *)xframe->packets)) {
usec = usec_diff(&now, &xbus->last_tx_sync); usec = ktime_us_delta(now, xbus->last_tx_sync);
xbus->last_tx_sync = now; xbus->last_tx_sync = now;
/* ignore startup statistics */ /* ignore startup statistics */
if (likely if (likely
@ -872,8 +866,7 @@ static inline void pcm_frame_out(xbus_t *xbus, xframe_t *xframe)
if ((rate_limit++ % 5003) == 0) if ((rate_limit++ % 5003) == 0)
XBUS_DBG(SYNC, xbus, XBUS_DBG(SYNC, xbus,
"Bad PCM TX timing(%d): " "Bad PCM TX timing(%d): usec=%lld.\n",
"usec=%ld.\n",
rate_limit, usec); rate_limit, usec);
} }
if (usec > xbus->max_tx_sync) if (usec > xbus->max_tx_sync)
@ -1187,11 +1180,10 @@ static void xbus_tick(xbus_t *xbus)
while ((xframe = xframe_dequeue(&xbus->pcm_tospan)) != NULL) { while ((xframe = xframe_dequeue(&xbus->pcm_tospan)) != NULL) {
copy_pcm_tospan(xbus, xframe); copy_pcm_tospan(xbus, xframe);
if (XPACKET_ADDR_SYNC((xpacket_t *)xframe->packets)) { if (XPACKET_ADDR_SYNC((xpacket_t *)xframe->packets)) {
struct timeval now; ktime_t now = ktime_get();
unsigned long usec; s64 usec;
do_gettimeofday(&now); usec = ktime_us_delta(now, xbus->last_rx_sync);
usec = usec_diff(&now, &xbus->last_rx_sync);
xbus->last_rx_sync = now; xbus->last_rx_sync = now;
/* ignore startup statistics */ /* ignore startup statistics */
if (likely if (likely
@ -1202,9 +1194,7 @@ static void xbus_tick(xbus_t *xbus)
if ((rate_limit++ % 5003) == 0) if ((rate_limit++ % 5003) == 0)
XBUS_DBG(SYNC, xbus, XBUS_DBG(SYNC, xbus,
"Bad PCM RX " "Bad PCM RX timing(%d): usec=%lld.\n",
"timing(%d): "
"usec=%ld.\n",
rate_limit, usec); rate_limit, usec);
} }
if (usec > xbus->max_rx_sync) if (usec > xbus->max_rx_sync)
@ -1235,7 +1225,7 @@ static void xbus_tick(xbus_t *xbus)
} }
} }
static void do_tick(xbus_t *xbus, const struct timeval *tv_received) static void do_tick(xbus_t *xbus, const ktime_t kt_received)
{ {
int counter = atomic_read(&xpp_tick_counter); int counter = atomic_read(&xpp_tick_counter);
unsigned long flags; unsigned long flags;
@ -1244,7 +1234,7 @@ static void do_tick(xbus_t *xbus, const struct timeval *tv_received)
if (global_ticker == xbus) if (global_ticker == xbus)
global_tick(); /* called from here or dahdi_sync_tick() */ global_tick(); /* called from here or dahdi_sync_tick() */
spin_lock_irqsave(&ref_ticker_lock, flags); spin_lock_irqsave(&ref_ticker_lock, flags);
xpp_drift_step(xbus, tv_received); xpp_drift_step(xbus, kt_received);
spin_unlock_irqrestore(&ref_ticker_lock, flags); spin_unlock_irqrestore(&ref_ticker_lock, flags);
if (likely(xbus->self_ticking)) if (likely(xbus->self_ticking))
xbus_tick(xbus); xbus_tick(xbus);
@ -1268,7 +1258,7 @@ void xframe_receive_pcm(xbus_t *xbus, xframe_t *xframe)
* FIXME: what about PRI split? * FIXME: what about PRI split?
*/ */
if (XPACKET_ADDR_SYNC((xpacket_t *)xframe->packets)) { if (XPACKET_ADDR_SYNC((xpacket_t *)xframe->packets)) {
do_tick(xbus, &xframe->tv_received); do_tick(xbus, xframe->kt_received);
atomic_inc(&xbus->pcm_rx_counter); atomic_inc(&xbus->pcm_rx_counter);
} else } else
xbus->xbus_frag_count++; xbus->xbus_frag_count++;

View File

@ -39,16 +39,6 @@ enum sync_mode {
SYNC_MODE_QUERY = 0x80, SYNC_MODE_QUERY = 0x80,
}; };
/*
* Abstract representation of timestamp.
* It would (eventually) replace the hard-coded
* timeval structs so we can migrate to better
* time representations.
*/
struct xpp_timestamp {
struct timeval tv;
};
/* /*
* A ticker encapsulates the timing information of some * A ticker encapsulates the timing information of some
* abstract tick source. The following tickers are used: * abstract tick source. The following tickers are used:
@ -60,8 +50,8 @@ struct xpp_timestamp {
struct xpp_ticker { /* for rate calculation */ struct xpp_ticker { /* for rate calculation */
int count; int count;
int cycle; int cycle;
struct xpp_timestamp first_sample; ktime_t first_sample;
struct xpp_timestamp last_sample; ktime_t last_sample;
int tick_period; /* usec/tick */ int tick_period; /* usec/tick */
spinlock_t lock; spinlock_t lock;
}; };
@ -75,7 +65,7 @@ struct xpp_drift {
int lost_ticks; /* occurances */ int lost_ticks; /* occurances */
int lost_tick_count; int lost_tick_count;
int sync_inaccuracy; int sync_inaccuracy;
struct xpp_timestamp last_lost_tick; ktime_t last_lost_tick;
long delta_sum; long delta_sum;
int offset_prev; int offset_prev;
int offset_range; int offset_range;
@ -88,15 +78,10 @@ struct xpp_drift {
void xpp_drift_init(xbus_t *xbus); void xpp_drift_init(xbus_t *xbus);
static inline long usec_diff(const struct timeval *tv1, static inline long usec_diff(const ktime_t *tv1,
const struct timeval *tv2) const ktime_t *tv2)
{ {
long diff_sec; return ktime_us_delta(*tv1, *tv2);
long diff_usec;
diff_sec = tv1->tv_sec - tv2->tv_sec;
diff_usec = tv1->tv_usec - tv2->tv_usec;
return diff_sec * 1000000 + diff_usec;
} }
int xbus_pcm_init(void *top); int xbus_pcm_init(void *top);

View File

@ -31,6 +31,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/delay.h> /* for msleep() to debug */ #include <linux/delay.h> /* for msleep() to debug */
#include <linux/sched.h> #include <linux/sched.h>
#include <dahdi/kernel.h>
#include "xpd.h" #include "xpd.h"
#include "xpp_dahdi.h" #include "xpp_dahdi.h"
#include "xbus-core.h" #include "xbus-core.h"
@ -117,24 +118,28 @@ static DEVICE_ATTR_READER(timing_show, dev, buf)
xbus_t *xbus; xbus_t *xbus;
struct xpp_drift *driftinfo; struct xpp_drift *driftinfo;
int len = 0; int len = 0;
struct timeval now; ktime_t now;
do_gettimeofday(&now); now = ktime_get();
xbus = dev_to_xbus(dev); xbus = dev_to_xbus(dev);
driftinfo = &xbus->drift; driftinfo = &xbus->drift;
len += len +=
snprintf(buf + len, PAGE_SIZE - len, "%-3s", snprintf(buf + len, PAGE_SIZE - len, "%-3s",
sync_mode_name(xbus->sync_mode)); sync_mode_name(xbus->sync_mode));
if (xbus->sync_mode == SYNC_MODE_PLL) { if (xbus->sync_mode == SYNC_MODE_PLL) {
bool pll_updated = !dahdi_ktime_equal(xbus->pll_updated_at,
ktime_set(0, 0));
s64 update_delta =
(!pll_updated) ? 0 :
xpp_ktime_sec_delta(now, xbus->pll_updated_at);
len += len +=
snprintf(buf + len, PAGE_SIZE - len, snprintf(buf + len, PAGE_SIZE - len,
" %5d: lost (%4d,%4d) : ", xbus->ticker.cycle, " %5d: lost (%4d,%4d) : ", xbus->ticker.cycle,
driftinfo->lost_ticks, driftinfo->lost_tick_count); driftinfo->lost_ticks, driftinfo->lost_tick_count);
len += len +=
snprintf(buf + len, PAGE_SIZE - len, snprintf(buf + len, PAGE_SIZE - len,
"DRIFT %3d %ld sec ago", xbus->sync_adjustment, "DRIFT %3d %lld sec ago", xbus->sync_adjustment,
(xbus->pll_updated_at == update_delta);
0) ? 0 : now.tv_sec - xbus->pll_updated_at);
} }
len += snprintf(buf + len, PAGE_SIZE - len, "\n"); len += snprintf(buf + len, PAGE_SIZE - len, "\n");
return len; return len;
@ -229,7 +234,7 @@ static DEVICE_ATTR_READER(driftinfo_show, dev, buf)
xbus_t *xbus; xbus_t *xbus;
struct xpp_drift *di; struct xpp_drift *di;
struct xpp_ticker *ticker; struct xpp_ticker *ticker;
struct timeval now; ktime_t now = ktime_get();
int len = 0; int len = 0;
int hours; int hours;
int minutes; int minutes;
@ -244,8 +249,7 @@ static DEVICE_ATTR_READER(driftinfo_show, dev, buf)
/* /*
* Calculate lost ticks time * Calculate lost ticks time
*/ */
do_gettimeofday(&now); seconds = ktime_ms_delta(now, di->last_lost_tick) / 1000;
seconds = now.tv_sec - di->last_lost_tick.tv.tv_sec;
minutes = seconds / 60; minutes = seconds / 60;
seconds = seconds % 60; seconds = seconds % 60;
hours = minutes / 60; hours = minutes / 60;

View File

@ -34,15 +34,15 @@ static void __xframe_dump_queue(struct xframe_queue *q)
xframe_t *xframe; xframe_t *xframe;
int i = 0; int i = 0;
char prefix[30]; char prefix[30];
struct timeval now; ktime_t now = ktime_get();
do_gettimeofday(&now);
printk(KERN_DEBUG "%s: dump queue '%s' (first packet in each frame)\n", printk(KERN_DEBUG "%s: dump queue '%s' (first packet in each frame)\n",
THIS_MODULE->name, q->name); THIS_MODULE->name, q->name);
list_for_each_entry_reverse(xframe, &q->head, frame_list) { list_for_each_entry_reverse(xframe, &q->head, frame_list) {
xpacket_t *pack = (xpacket_t *)&xframe->packets[0]; xpacket_t *pack = (xpacket_t *)&xframe->packets[0];
long usec = usec_diff(&now, &xframe->tv_queued); s64 usec = ktime_us_delta(now, xframe->kt_queued);
snprintf(prefix, ARRAY_SIZE(prefix), " %3d> %5ld.%03ld msec",
snprintf(prefix, ARRAY_SIZE(prefix), " %3d> %5lld.%03lld msec",
i++, usec / 1000, usec % 1000); i++, usec / 1000, usec % 1000);
dump_packet(prefix, pack, 1); dump_packet(prefix, pack, 1);
} }
@ -60,9 +60,7 @@ static bool __xframe_enqueue(struct xframe_queue *q, xframe_t *xframe)
if (q->count >= q->max_count) { if (q->count >= q->max_count) {
q->overflows++; q->overflows++;
if ((overflow_cnt++ % 1000) < 5) { if ((overflow_cnt++ % 1000) < 5) {
NOTICE("Overflow of %-15s: counts %3d, %3d, %3d " NOTICE("Overflow of %-15s: counts %3d, %3d, %3d worst %3d, overflows %3d worst_lag %02lld.%lld ms\n",
"worst %3d, overflows %3d "
"worst_lag %02ld.%ld ms\n",
q->name, q->steady_state_count, q->count, q->name, q->steady_state_count, q->count,
q->max_count, q->worst_count, q->overflows, q->max_count, q->worst_count, q->overflows,
q->worst_lag_usec / 1000, q->worst_lag_usec / 1000,
@ -75,7 +73,7 @@ static bool __xframe_enqueue(struct xframe_queue *q, xframe_t *xframe)
if (++q->count > q->worst_count) if (++q->count > q->worst_count)
q->worst_count = q->count; q->worst_count = q->count;
list_add_tail(&xframe->frame_list, &q->head); list_add_tail(&xframe->frame_list, &q->head);
do_gettimeofday(&xframe->tv_queued); xframe->kt_queued = ktime_get();
out: out:
return ret; return ret;
} }
@ -96,8 +94,8 @@ static xframe_t *__xframe_dequeue(struct xframe_queue *q)
{ {
xframe_t *frm = NULL; xframe_t *frm = NULL;
struct list_head *h; struct list_head *h;
struct timeval now; ktime_t now;
unsigned long usec_lag; s64 usec_lag;
if (list_empty(&q->head)) if (list_empty(&q->head))
goto out; goto out;
@ -105,12 +103,8 @@ static xframe_t *__xframe_dequeue(struct xframe_queue *q)
list_del_init(h); list_del_init(h);
--q->count; --q->count;
frm = list_entry(h, xframe_t, frame_list); frm = list_entry(h, xframe_t, frame_list);
do_gettimeofday(&now); now = ktime_get();
usec_lag = usec_lag = ktime_us_delta(now, frm->kt_queued);
(now.tv_sec - frm->tv_queued.tv_sec) * 1000 * 1000 + (now.tv_usec -
frm->
tv_queued.
tv_usec);
if (q->worst_lag_usec < usec_lag) if (q->worst_lag_usec < usec_lag)
q->worst_lag_usec = usec_lag; q->worst_lag_usec = usec_lag;
out: out:
@ -284,7 +278,7 @@ xframe_t *get_xframe(struct xframe_queue *q)
BUG_ON(xframe->xframe_magic != XFRAME_MAGIC); BUG_ON(xframe->xframe_magic != XFRAME_MAGIC);
atomic_set(&xframe->frame_len, 0); atomic_set(&xframe->frame_len, 0);
xframe->first_free = xframe->packets; xframe->first_free = xframe->packets;
do_gettimeofday(&xframe->tv_created); xframe->kt_created = ktime_get();
/* /*
* If later parts bother to correctly initialize their * If later parts bother to correctly initialize their
* headers, there is no need to memset() the whole data. * headers, there is no need to memset() the whole data.

View File

@ -19,7 +19,7 @@ struct xframe_queue {
/* statistics */ /* statistics */
unsigned int worst_count; unsigned int worst_count;
unsigned int overflows; unsigned int overflows;
unsigned long worst_lag_usec; /* since xframe creation */ s64 worst_lag_usec; /* since xframe creation */
}; };
void xframe_queue_init(struct xframe_queue *q, unsigned int steady_state_count, void xframe_queue_init(struct xframe_queue *q, unsigned int steady_state_count,

View File

@ -200,7 +200,7 @@ struct xusb {
int counters[XUSB_COUNTER_MAX]; int counters[XUSB_COUNTER_MAX];
/* metrics */ /* metrics */
struct timeval last_tx; ktime_t last_tx;
unsigned int max_tx_delay; unsigned int max_tx_delay;
uint usb_tx_delay[NUM_BUCKETS]; uint usb_tx_delay[NUM_BUCKETS];
uint sluggish_debounce; uint sluggish_debounce;
@ -365,7 +365,7 @@ static int do_send_xframe(xbus_t *xbus, xframe_t *xframe)
BUG_ON(!urb); BUG_ON(!urb);
/* update urb length */ /* update urb length */
urb->transfer_buffer_length = XFRAME_LEN(xframe); urb->transfer_buffer_length = XFRAME_LEN(xframe);
do_gettimeofday(&xframe->tv_submitted); xframe->kt_submitted = ktime_get();
ret = usb_submit_urb(urb, GFP_ATOMIC); ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret < 0) { if (ret < 0) {
static int rate_limit; static int rate_limit;
@ -863,8 +863,8 @@ static void xpp_send_callback(struct urb *urb)
xframe_t *xframe = &uframe->xframe; xframe_t *xframe = &uframe->xframe;
xusb_t *xusb = uframe->xusb; xusb_t *xusb = uframe->xusb;
xbus_t *xbus = xbus_num(xusb->xbus_num); xbus_t *xbus = xbus_num(xusb->xbus_num);
struct timeval now; ktime_t now;
long usec; s64 usec;
int writes = atomic_read(&xusb->pending_writes); int writes = atomic_read(&xusb->pending_writes);
int i; int i;
@ -875,9 +875,9 @@ static void xpp_send_callback(struct urb *urb)
} }
//flip_parport_bit(6); //flip_parport_bit(6);
atomic_dec(&xusb->pending_writes); atomic_dec(&xusb->pending_writes);
do_gettimeofday(&now); now = ktime_get();
xusb->last_tx = xframe->tv_submitted; xusb->last_tx = xframe->kt_submitted;
usec = usec_diff(&now, &xframe->tv_submitted); usec = ktime_us_delta(now, xframe->kt_submitted);
if (usec < 0) if (usec < 0)
usec = 0; /* System clock jumped */ usec = 0; /* System clock jumped */
if (usec > xusb->max_tx_delay) if (usec > xusb->max_tx_delay)
@ -931,9 +931,8 @@ static void xpp_receive_callback(struct urb *urb)
xbus_t *xbus = xbus_num(xusb->xbus_num); xbus_t *xbus = xbus_num(xusb->xbus_num);
size_t size; size_t size;
bool do_resubmit = 1; bool do_resubmit = 1;
struct timeval now; ktime_t now = ktime_get();
do_gettimeofday(&now);
atomic_dec(&xusb->pending_reads); atomic_dec(&xusb->pending_reads);
if (!xbus) { if (!xbus) {
XUSB_ERR(xusb, XUSB_ERR(xusb,
@ -961,7 +960,7 @@ static void xpp_receive_callback(struct urb *urb)
goto err; goto err;
} }
atomic_set(&xframe->frame_len, size); atomic_set(&xframe->frame_len, size);
xframe->tv_received = now; xframe->kt_received = now;
// if (debug) // if (debug)
// dump_xframe("USB_FRAME_RECEIVE", xbus, xframe, debug); // dump_xframe("USB_FRAME_RECEIVE", xbus, xframe, debug);

View File

@ -283,9 +283,8 @@ out:
int xframe_receive(xbus_t *xbus, xframe_t *xframe) int xframe_receive(xbus_t *xbus, xframe_t *xframe)
{ {
int ret = 0; int ret = 0;
struct timeval now; ktime_t kt_received;
struct timeval tv_received; s64 usec;
int usec;
if (XFRAME_LEN(xframe) < RPACKET_HEADERSIZE) { if (XFRAME_LEN(xframe) < RPACKET_HEADERSIZE) {
static int rate_limit; static int rate_limit;
@ -301,7 +300,7 @@ int xframe_receive(xbus_t *xbus, xframe_t *xframe)
XBUS_DBG(GENERAL, xbus, "Dropped xframe. Is shutting down.\n"); XBUS_DBG(GENERAL, xbus, "Dropped xframe. Is shutting down.\n");
return -ENODEV; return -ENODEV;
} }
tv_received = xframe->tv_received; kt_received = xframe->kt_received;
/* /*
* We want to check that xframes do not mix PCM and other commands * We want to check that xframes do not mix PCM and other commands
*/ */
@ -315,10 +314,7 @@ int xframe_receive(xbus_t *xbus, xframe_t *xframe)
ret = xframe_receive_cmd(xbus, xframe); ret = xframe_receive_cmd(xbus, xframe);
} }
/* Calculate total processing time */ /* Calculate total processing time */
do_gettimeofday(&now); usec = ktime_us_delta(ktime_get(), kt_received);
usec =
(now.tv_sec - tv_received.tv_sec) * 1000000 + now.tv_usec -
tv_received.tv_usec;
if (usec > xbus->max_rx_process) if (usec > xbus->max_rx_process)
xbus->max_rx_process = usec; xbus->max_rx_process = usec;
return ret; return ret;