Hi, > -----Original Message----- > > On 11/18/21 5:18 AM, Heikki Krogerus wrote: > > Hi, > > > > On Thu, Nov 18, 2021 at 05:23:52PM +0800, Xu Yang wrote: > >> @@ -6428,6 +6432,9 @@ void tcpm_unregister_port(struct tcpm_port > *port) > >> { > >> int i; > > > > You need to take the port lock here, no? > > > > mutex_lock(&port->lock); > > > >> + kthread_destroy_worker(port->wq); > >> + port->wq = NULL; > > > > mutex_unlock(&port->lock); > > > > I don't think the timer code runs under the lock, so that won't help. > But, yes, the code is inherently racy. At the very least, port->wq > would have to be set to NULL first, but even that would have to be > synchronized. I wonder how other drivers handle that situation. > > Guenter > Actually, the race is unlikely to happen if the hrtimer's expire time is a little bigger. But it's better to avoid this situation from happening. So it may be necessary to use a flag to indicate to the hrtimer the port is going to be unregistered and it's no need to queue work anymore. The patch maybe like following: struct tcpm_port *tcpm_register_port(...) { ... port->registered = true; return; } static enum hrtimer_restart state_machine_timer_handler(timer) { if (port->registered) kthread_queue_work(port->wq, work); return HRTIMER_NORESTART; } void tcpm_unregister_port(port) { port->registered = false; kthread_destroy_worker(port->wq); hrtimer_cancel(&timer); ... } What about this idea? Or I will submit it as patch V2. Xu Yang