From: Aaron Taylor Date: Wed, 28 Apr 2021 08:01:31 +0000 (-0700) Subject: Updated host/linvcons.c to use new timer API introduced in Linux 4.14.0. X-Git-Tag: first-build~23 X-Git-Url: https://git.subgeniuskitty.com/xeon-phi-kernel-module/.git/commitdiff_plain/f4a476d15921ee97ff3f23147e5119e25bc561cb Updated host/linvcons.c to use new timer API introduced in Linux 4.14.0. See also: - https://lwn.net/Articles/735887/ - https://stackoverflow.com/questions/53839625 --- diff --git a/host/linvcons.c b/host/linvcons.c index 556a9b5..7c3e58d 100644 --- a/host/linvcons.c +++ b/host/linvcons.c @@ -43,7 +43,7 @@ static int micvcons_write(struct tty_struct * tty, const unsigned char *buf, int count); static int micvcons_write_room(struct tty_struct *tty); static void micvcons_set_termios(struct tty_struct *tty, struct ktermios * old); -static void micvcons_timeout(unsigned long); +static void micvcons_timeout(struct timer_list *); static void micvcons_throttle(struct tty_struct *tty); static void micvcons_unthrottle(struct tty_struct *tty); static void micvcons_wakeup_readbuf(struct work_struct *work); @@ -62,10 +62,19 @@ static struct tty_operations micvcons_tty_ops = { static struct tty_driver *micvcons_tty = NULL; static u16 extra_timeout = 0; static u8 restart_timer_flag = MICVCONS_TIMER_RESTART; -static struct timer_list vcons_timer; -static struct list_head timer_list_head; static spinlock_t timer_list_lock; +// The timer API introduced in Linux 4.14.0 includes a from_timer() macro built +// atop the container_of() macro. As the kernel moves away from using +// timer_list.data, it quasi-assumes that the timer_list struct will be +// contained in some larger struct that also contains the data, hence this +// timer_wrapper struct since it allows us to avoid any serious code changes to +// the driver. +static struct timer_wrapper { + struct timer_list vcons_timer; + struct list_head timer_list_head; +} timer_wrapper ; + int micvcons_create(int num_bds) { @@ -75,7 +84,7 @@ micvcons_create(int num_bds) char wq_name[14]; struct device *dev; - INIT_LIST_HEAD(&timer_list_head); + INIT_LIST_HEAD(&timer_wrapper.timer_list_head); if (micvcons_tty) goto exit; @@ -145,9 +154,7 @@ micvcons_create(int num_bds) } INIT_WORK(&port->dp_wakeup_read_buf, micvcons_wakeup_readbuf); } - vcons_timer.function = micvcons_timeout; - vcons_timer.data = (unsigned long)(&timer_list_head); - init_timer(&vcons_timer); + timer_setup(&timer_wrapper.vcons_timer, micvcons_timeout, 0); exit: return ret; } @@ -215,10 +222,10 @@ micvcons_open(struct tty_struct * tty, struct file * filp) if (ret != 0) goto exit_locked; spin_lock(&timer_list_lock); - list_add_tail_rcu(&port->list_member, &timer_list_head); - if (list_is_singular(&timer_list_head)) { + list_add_tail_rcu(&port->list_member, &timer_wrapper.timer_list_head); + if (list_is_singular(&timer_wrapper.timer_list_head)) { restart_timer_flag = MICVCONS_TIMER_RESTART; - mod_timer(&vcons_timer, jiffies + + mod_timer(&timer_wrapper.vcons_timer, jiffies + msecs_to_jiffies(MICVCONS_SHORT_TIMEOUT)); } spin_unlock(&timer_list_lock); @@ -235,10 +242,10 @@ micvcons_del_timer_entry(micvcons_port_t *port) { spin_lock(&timer_list_lock); list_del_rcu(&port->list_member); - if (list_empty(&timer_list_head)) { + if (list_empty(&timer_wrapper.timer_list_head)) { restart_timer_flag = MICVCONS_TIMER_SHUTDOWN; spin_unlock(&timer_list_lock); - del_timer_sync(&vcons_timer); + del_timer_sync(&timer_wrapper.vcons_timer); } else { spin_unlock(&timer_list_lock); } @@ -499,9 +506,10 @@ micvcons_wakeup_readbuf(struct work_struct *work) } static void -micvcons_timeout(unsigned long data) +micvcons_timeout(struct timer_list *t) { - struct list_head *timer_list_ptr = (struct list_head *)data; + struct timer_wrapper *tm_wrap = from_timer(tm_wrap, t, vcons_timer); + struct list_head *timer_list_ptr = &tm_wrap->timer_list_head; micvcons_port_t *port; u8 console_active = 0; int num_chars_read = 0; @@ -519,7 +527,7 @@ micvcons_timeout(unsigned long data) extra_timeout = (console_active ? 0 : extra_timeout + MICVCONS_SHORT_TIMEOUT); extra_timeout = min(extra_timeout, (u16)MICVCONS_MAX_TIMEOUT); - mod_timer(&vcons_timer, jiffies + + mod_timer(&timer_wrapper.vcons_timer, jiffies + msecs_to_jiffies(MICVCONS_SHORT_TIMEOUT+extra_timeout)); } spin_unlock(&timer_list_lock);