ChangeSet 1.889.26.5, 2003/01/11 23:49:13-08:00, baldrick@wanadoo.fr [PATCH] get rid of speedtouch kernel thread speedtouch: remove the kernel thread and all the junk that went with it. The work it did can all be done in interrupt context, so use a tasklet instead. diff -Nru a/drivers/usb/misc/speedtouch.c b/drivers/usb/misc/speedtouch.c --- a/drivers/usb/misc/speedtouch.c Mon Jan 13 14:27:42 2003 +++ b/drivers/usb/misc/speedtouch.c Mon Jan 13 14:27:42 2003 @@ -57,6 +57,7 @@ #include #include #include +#include #include #include @@ -138,6 +139,7 @@ struct udsl_instance_data { int minor; + struct tasklet_struct recvqueue_tasklet; /* usb device part */ struct usb_device *usb_dev; @@ -159,11 +161,7 @@ static const char udsl_driver_name[] = "Alcatel SpeedTouch USB"; -/* data thread */ -DECLARE_WAIT_QUEUE_HEAD (udsl_wqh); -static DECLARE_COMPLETION(thread_grave); static DECLARE_MUTEX(udsl_usb_ioctl_lock); -static unsigned int datapid; #ifdef DEBUG_PACKET int udsl_print_packet (const unsigned char *data, int len); @@ -178,7 +176,7 @@ static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg); static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb); int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page); -void udsl_atm_processqueue (struct udsl_instance_data *instance); +void udsl_atm_processqueue (unsigned long data); static struct atmdev_ops udsl_atm_devops = { .open = udsl_atm_open, @@ -372,8 +370,9 @@ }; -void udsl_atm_processqueue (struct udsl_instance_data *instance) +void udsl_atm_processqueue (unsigned long data) { + struct udsl_instance_data *instance = (struct udsl_instance_data *) data; struct atmsar_vcc_data *atmsar_vcc = NULL; struct sk_buff *new = NULL, *skb = NULL, *tmp = NULL; unsigned long iflags; @@ -437,66 +436,6 @@ PDEBUG ("udsl_atm_processqueue successfull\n"); } -int udsl_atm_processqueue_thread (void *data) -{ - int i = 0; - DECLARE_WAITQUEUE (wait, current); - - lock_kernel (); - daemonize (); - - /* Setup a nice name */ - strcpy (current->comm, "kSpeedSARd"); - - add_wait_queue (&udsl_wqh, &wait); - set_current_state(TASK_INTERRUPTIBLE); - - for (;;) { - schedule(); - if (signal_pending (current)) - break; - PDEBUG ("SpeedSARd awoke\n"); -retry: - for (i = 0; i < MAX_UDSL; i++) - if (minor_data[i]) - udsl_atm_processqueue (minor_data[i]); - set_current_state(TASK_INTERRUPTIBLE); - /* we must check for data recieved and restart processing if there's any */ - for (i = 0; i < MAX_UDSL; i++) { - spin_lock_irq(&minor_data[i]->recvqlock); - if (!skb_queue_empty(&minor_data[i]->recvqueue)) { - spin_unlock_irq(&minor_data[i]->recvqlock); - set_current_state(TASK_RUNNING); - goto retry; - } else { - spin_unlock_irq(&minor_data[i]->recvqlock); - } - } - }; - - set_current_state(TASK_RUNNING); - remove_wait_queue (&udsl_wqh, &wait); - PDEBUG ("SpeedSARd is exiting\n"); - complete_and_exit(&thread_grave, 0); - return 0; //never reached -} - - -void udsl_atm_sar_start (void) -{ - datapid = kernel_thread (udsl_atm_processqueue_thread, (void *) NULL, - CLONE_FS | CLONE_FILES | CLONE_SIGHAND); -} - -void udsl_atm_sar_stop (void) -{ - int ret; - /* Kill the thread */ - ret = kill_proc (datapid, SIGTERM, 1); - if (!ret) { - wait_for_completion(&thread_grave); - } -} /*************************************************************************** * @@ -739,7 +678,7 @@ spin_lock (&instance->recvqlock); skb_queue_tail (&instance->recvqueue, ctx->skb); spin_unlock (&instance->recvqlock); - wake_up (&udsl_wqh); + tasklet_schedule (&instance->recvqueue_tasklet); /* get a new skb */ ctx->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE); if (!ctx->skb) { @@ -975,6 +914,7 @@ instance->rcvbufs = NULL; spin_lock_init (&instance->sndqlock); spin_lock_init (&instance->recvqlock); + tasklet_init (&instance->recvqueue_tasklet, udsl_atm_processqueue, (unsigned long) instance); udsl_atm_startdevice (instance, &udsl_atm_devops); @@ -1032,16 +972,11 @@ for (i = 0; i < MAX_UDSL; i++) minor_data[i] = NULL; - init_waitqueue_head (&udsl_wqh); - udsl_atm_sar_start (); - return usb_register (&udsl_usb_driver); } static void __exit udsl_usb_cleanup (void) { - /* killing threads */ - udsl_atm_sar_stop (); usb_deregister (&udsl_usb_driver); }