예제 #1
0
static int ipc_load_test_thread(void *data)
{
	int cpu = *((int *)data);
	ICP_LOAD_TEST *lt = &obj[cpu].loadtest;
	char strg[20];
	if (cpu > num_online_cpus()) {
		printk(KERN_ERR "%s: bad cpu number 0x%x\n", __func__, cpu);
		return -1;
	}
	sprintf(strg, "loadTest/%d", cpu);
	daemonize(strg);

	if (lt->threadPriority > 0) {
		struct sched_param param;
		param.sched_priority = (lt->threadPriority < MAX_RT_PRIO) ?
		    lt->threadPriority : (MAX_RT_PRIO - 1);
		sched_setscheduler(current, SCHED_FIFO, &param);
	}

	allow_signal(SIGKILL);
	allow_signal(SIGTERM);

	/* Run until signal received */
	while (1) {
		if (down_interruptible(&lt->threadSemaphore) == 0) {
			ipc_load(cpu);
		} else
			break;
	}
	complete_and_exit(&lt->threadCompletion, 0);
}
예제 #2
0
void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
{

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
    daemonize(pThreadName /*"%s",pAd->net_dev->name*/);

    allow_signal(SIGTERM);
    allow_signal(SIGKILL);
    current->flags |= PF_NOFREEZE;
#else
    unsigned long flags;

    daemonize();
    reparent_to_init();
    strcpy(current->comm, pThreadName);

    siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));

    /* Allow interception of SIGKILL only
     * Don't allow other signals to interrupt the transmission */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
    spin_lock_irqsave(&current->sigmask_lock, flags);
    flush_signals(current);
    recalc_sigpending(current);
    spin_unlock_irqrestore(&current->sigmask_lock, flags);
#endif
#endif

    /* signal that we've started the thread */
    complete(pNotify);

}
예제 #3
0
void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
{
	daemonize(pThreadName /*"%s",pAd->net_dev->name*/);

	allow_signal(SIGTERM);
	allow_signal(SIGKILL);
	current->flags |= PF_NOFREEZE;

	/* signal that we've started the thread */
	complete(pNotify);
}
예제 #4
0
int producer(void* arg)
{
	struct job *new_job;
	unsigned int i;

	allow_signal(SIGKILL);

	while (!kthread_should_stop())
	{
		new_job=(struct job*)kmalloc(sizeof(struct job), GFP_KERNEL);
		if (new_job == NULL) 
		{
			printk("Unable to allocate the job structure\n");
			return -1;
		}

		enqueue_job(new_job);
		get_random_bytes(&i, sizeof(i));
		ssleep(i % 5);
		if (signal_pending(current))
			break;
	}
	printk(KERN_INFO "Producer Thread Stopping\n");
	thread_prod = NULL;
	do_exit(0);
}
예제 #5
0
파일: tikle_fh.c 프로젝트: gmoliveira/tikle
/**
 * Stop the trigger.
 *
 * @param base the actual jiffies.
 * @return void
 */
static void tikle_stop_trigger(unsigned int base)
{
	lock_kernel();
	current->flags |= PF_NOFREEZE;
	daemonize("thread stop trigger");
	allow_signal(SIGKILL);
	unlock_kernel();

	/*
	 * do you believe in micracles?
	 * not a method, not a technique,
	 * just cheating a kernel timer ;]
	 * nf_[un]register_hook() does not
	 * execute friendly with timers
	 * since its atomic implementation
	 *
	 * for more information go to:
	 * http://www.makelinux.net/ldd3/chp-7-sect-4.shtml
	 */ 
	for (; jiffies <= (base + msecs_to_jiffies(faultload[tikle_timers[tikle_num_timers-1].trigger_id].op_value[0].num * 1000)););

	nf_unregister_hook(&tikle_pre_hook);
	nf_unregister_hook(&tikle_post_hook);

	//nf_unregister_queue_handler(PF_INET, &qh);

	tikle_send_log();
}
예제 #6
0
thread_return rtw_xmit_thread(thread_context context)
{
	s32 err;
	PADAPTER padapter;


	err = _SUCCESS;
	padapter = (PADAPTER)context;

#if 0
	thread_enter(padapter->pnetdev);
#else
//	daemonize("%s", padapter->pnetdev->name);
	daemonize("%s", "RTW_XMIT_THREAD");
	allow_signal(SIGTERM);
#endif

	do {
		err = hal_xmit_handler(padapter);
		if (signal_pending(current)) {
			flush_signals(current);
		}
	} while (_SUCCESS == err);

	_rtw_up_sema(&padapter->xmitpriv.terminate_xmitthread_sema);

	thread_exit();
}
예제 #7
0
static int
ald_daemon(void *arg)
{
	int needwakeup;
	struct alq *alq;

	daemonize("ALQ Daemon");
	allow_signal(SIGKILL);

	ALD_LOCK();

	for (;;) {
		if ((alq = LIST_FIRST(&ald_active)) == NULL)
			ALD_WAIT((alq = LIST_FIRST(&ald_active)) != NULL);

		if (signal_pending(current))
			break;

		spin_lock_irq(&alq->aq_lock);
		ald_deactivate(alq);
		ALD_UNLOCK();
		needwakeup = alq_doio(alq);
		spin_unlock_irq(&alq->aq_lock);
		if (needwakeup)
			wake_up_interruptible(&alq->aq_waitq);
		ALD_LOCK();
	}

	ALD_UNLOCK();

	return 0;
}
예제 #8
0
파일: thread4.c 프로젝트: zxwitsme/configs
int my_fuction(void *arg)
{

    printk(" in %s()\n", __FUNCTION__);

    allow_signal(SIGKILL); //使得线程可以接收SIGKILL信号

    mdelay(2000);

    printk(" my_function complete()\n");

    printk("should stop: %d\n",kthread_should_stop());

    while (!signal_pending(current) && !kthread_should_stop()) {//使得线程可以可以被杀死,也可以再rmmod的时候结束

        printk(" jiffies is %lu\n", jiffies);

        set_current_state(TASK_INTERRUPTIBLE);

        schedule_timeout(HZ * 5);   

         printk("should stop: %d\n",kthread_should_stop());

    }

    printk("Leaving my_function\n");

    flag = 1; //flag很关键!

    return 0;

}
예제 #9
0
static int thread_fn(void *thread_id)
{
	int id;
	allow_signal(SIGKILL);

	while (!kthread_should_stop()) 
	{
		struct job* next_job;
		if (down_interruptible(&my_sem))
		{
			printk(KERN_INFO "Unable to hold the semaphore\n");
			break;
		}

		mutex_lock(&my_mutex);
		if (job_queue == NULL)
			next_job = NULL;
		else
		{
			next_job = job_queue;
			job_queue = job_queue->next;
		}
		mutex_unlock (&my_mutex);
		if (next_job == NULL)
			break;
		process_job (thread_id, next_job);
		kfree (next_job);
		if (signal_pending(current))
			break;
	}
	id = *(int *)thread_id;
	thread_cons[id] = NULL;
	printk(KERN_INFO "Consumer Thread Stopping\n");
	do_exit(0);
}
예제 #10
0
static int
knamed_loop(void *data)
{
    allow_signal(SIGHUP);

    while (1) {
        set_current_state(TASK_INTERRUPTIBLE);

        if (kthread_should_stop()) {
            break;
        }

        if (signal_pending(current)) {
            flush_signals(current);

            PR_INFO("SIGNAL received");
        }

        PR_INFO("Hello knamed_task");

        schedule_timeout(5 * HZ);
    }

    knamed_task = NULL;

    complete_and_exit(&comp, 0);
}
예제 #11
0
int cec_task(void* dummy)
{
  dprintk(2, "cec_task started\n");

  daemonize("cec_repeater");

  allow_signal(SIGTERM);

  sema_init(&sendCommand, 0);
  notEndTask = 1;

  while (notEndTask) {
    dprintk(4, "sendCommand - down ->\n");
    down(&sendCommand);
    dprintk(4, "sendCommand - down <-\n");
    if (!notEndTask) break;

      if(sendCommandWithDelay--)
        udelay(10000);

      if(sizeOfSendBuf == 1) // PING
      {
        cec_start_sending(1);
      }
      else
      {
        cec_start_sending(0);
      }
    //udelay(10000);
  }

  notEndTask = 1;
  dprintk(2, "task died\n");
  return 0;
}
int my_kthread_entry_function (void *data)
{
	int count;
        printk(KERN_ERR" In kthread function with arg : %x \n", (unsigned int)data);
	allow_signal(SIGTERM);

	for(count=0; count < 10; count++) {

		// Print tick messages
		printk(KERN_ERR" kthread function .. tick %lu \n", jiffies);

		msleep_interruptible(30000);//TODO need to findout a way to exit when kthread_stop is called
		/*
		 * When someone calls kthread_stop() on your kthread, it will be woken
		 * and kthread_should_stop() will return true.  You should then return from kthread, and your return
		 * value will be passed through to kthread_stop().
		*/
		if(kthread_should_stop())
		{
			printk(KERN_ERR" kthread_stop initiated exit at %lu \n", jiffies);
			return -1; //Exit from the thread. Return value will be passed to kthread_stop()
		}

	}
	// Exit from the thread
	printk(KERN_ERR" kthread function exits at %lu \n", jiffies);
	do_exit(0);
}
예제 #13
0
static int dosm_kthread(void *arg)
{
    int i;

    allow_signal(SIGKILL);
    set_current_state(TASK_INTERRUPTIBLE);

    while (!kthread_should_stop()) {
        if (down_interruptible(&scan_sem) != 0)
            continue;

        for (i = 0; i < packet_buf_cap; ++i) {
            if ((packet_buf[i].source_flags & DOSM_SF_VALID) &&
                    !(packet_buf[i].remote_flags & DOSM_RF_CHECKED)) {
                packet_buf[i].remote_flags |= DOSM_RF_CHECKED;
                printk(KERN_ALERT
                       "processing packet %d from %d\n", i,
                       packet_buf[i].source_lapic);
                dosm_packet_process(packet_buf + i);
            }
        }
    }

    return 0;
}
예제 #14
0
int kcdfsd_thread(void *unused){
  kcdfsd_running = 1;

  /*
   * This thread doesn't need any user-level access,
   * so get rid of all our resources
   */
#ifdef OLD_KERNEL
  exit_files(current);  /* daemonize doesn't do exit_files */
  daemonize();
#else
  daemonize("k"FSNAME"d");

  /* Allow SIGTERM to quit properly when removing module */
  /* By default with daemonize all signals are dropped */
  allow_signal(SIGTERM);
#endif

  /* Setup a nice name */
  strcpy(current->comm, "k"FSNAME"d");

  /* Send me a signal to get me die */
  do {
    kcdfsd_process_request();
    interruptible_sleep_on(&kcdfsd_wait);
  } while (!signal_pending(current));

  kcdfsd_running = 0;
  return 0;
}
예제 #15
0
int nuvotonTask(void * dummy)
{
    daemonize("nuvotonTask");

    allow_signal(SIGTERM);

    while(1)
    {
        int dataAvailable = 0;

        if (wait_event_interruptible(rx_wq, (RCVBufferStart != RCVBufferEnd)))
        {
            printk("wait_event_interruptible failed\n");
            continue;
        }

        if (RCVBufferStart != RCVBufferEnd)
            dataAvailable = 1;

        while (dataAvailable)
        {
            processResponse();

            if (RCVBufferStart == RCVBufferEnd)
                dataAvailable = 0;

            dprintk(150, "start %d end %d\n",  RCVBufferStart,  RCVBufferEnd);
        }
    }

    printk("nuvotonTask died!\n");

    return 0;
}
예제 #16
0
파일: wait_thunder.c 프로젝트: sysplay/bbb
static int thread_fn(void *data)
{
    allow_signal(SIGKILL);
    if (data == NULL)
    {
        printk("Data is NULL\n");
        return -1;
    }
    printk("Data is %d\n", *(int *)data);

    if (down_interruptible(&sem))
        return -ERESTARTSYS;

    while (flag != 'y')
    {
        up(&sem);
        printk("Thread %d going to Sleep\n", *(int *)data);
        if (wait_event_interruptible(wq, flag == 'y'))
            return -ERESTARTSYS;

        printk("Thread %d Woken Up\n", *(int *)data);
        if (down_interruptible(&sem))
            return -ERESTARTSYS;
    }
    ssleep(1);
    flag = 'n';
    up(&sem);

    printk("Data read by %d thread is %c\n", *(int *)data, c);
    thread_st[*(int *)data] = NULL;
    do_exit(0);
}
예제 #17
0
static int test_func(void *data)
{
	struct test_thread_data *td = data;
	int ret;

	current->flags |= PF_MUTEX_TESTER;
	set_freezable();
	allow_signal(SIGHUP);

	for(;;) {

		set_current_state(TASK_INTERRUPTIBLE);

		if (td->opcode > 0) {
			set_current_state(TASK_RUNNING);
			ret = handle_op(td, 0);
			set_current_state(TASK_INTERRUPTIBLE);
			td->opcode = ret;
		}

		/* Wait for the next command to be executed */
		schedule();
		try_to_freeze();

		if (signal_pending(current))
			flush_signals(current);

		if(kthread_should_stop())
			break;
	}
	return 0;
}
예제 #18
0
/* Keventd can't block, but this (a child) can. */
static int wait_for_helper(void *data)
{
	struct subprocess_info *sub_info = data;
	pid_t pid;
	struct k_sigaction sa;

	/* Install a handler: if SIGCLD isn't handled sys_wait4 won't
	 * populate the status, but will return -ECHILD. */
	sa.sa.sa_handler = SIG_IGN;
	sa.sa.sa_flags = 0;
	siginitset(&sa.sa.sa_mask, sigmask(SIGCHLD));
	do_sigaction(SIGCHLD, &sa, (struct k_sigaction *)0);
	allow_signal(SIGCHLD);

	pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD);
	if (pid < 0) {
		sub_info->retval = pid;
	} else {
		/*
		 * Normally it is bogus to call wait4() from in-kernel because
		 * wait4() wants to write the exit code to a userspace address.
		 * But wait_for_helper() always runs as keventd, and put_user()
		 * to a kernel address works OK for kernel threads, due to their
		 * having an mm_segment_t which spans the entire address space.
		 *
		 * Thus the __user pointer cast is valid here.
		 */
		sys_wait4(pid, (int __user *) &sub_info->retval, 0, NULL);
	}

	complete(sub_info->complete);
	return 0;
}
예제 #19
0
int thread_fn2(void *dummy) 
{
	allow_signal(SIGKILL);
	printk("Thread 2 going to sleep\n");
	ssleep(5);
	i = 1;
	printk("Thread 2 out of sleep\n");
	thread2 = NULL;
	return 0;
}
예제 #20
0
int thread_fn2(void *dummy) 
{
	allow_signal(SIGKILL);
	printk(KERN_INFO "spinlkgpio:thread_fn2: Thread 2 going to sleep\n");
	ssleep(20);
	i = 1;
	printk(KERN_INFO "spinlkgpio:thread_fn2: Thread 2 out of sleep\n");
	thread2 = NULL;
	return 0;
}
예제 #21
0
파일: svc.c 프로젝트: AlexShiLucky/linux
/*
 * This is the lockd kernel thread
 */
static int
lockd(void *vrqstp)
{
	int		err = 0;
	struct svc_rqst *rqstp = vrqstp;
	struct net *net = &init_net;
	struct lockd_net *ln = net_generic(net, lockd_net_id);

	/* try_to_freeze() is called from svc_recv() */
	set_freezable();

	/* Allow SIGKILL to tell lockd to drop all of its locks */
	allow_signal(SIGKILL);

	dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n");

	/*
	 * The main request loop. We don't terminate until the last
	 * NFS mount or NFS daemon has gone away.
	 */
	while (!kthread_should_stop()) {
		long timeout = MAX_SCHEDULE_TIMEOUT;
		RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);

		/* update sv_maxconn if it has changed */
		rqstp->rq_server->sv_maxconn = nlm_max_connections;

		if (signalled()) {
			flush_signals(current);
			restart_grace();
			continue;
		}

		timeout = nlmsvc_retry_blocked();

		/*
		 * Find a socket with data available and call its
		 * recvfrom routine.
		 */
		err = svc_recv(rqstp, timeout);
		if (err == -EAGAIN || err == -EINTR)
			continue;
		dprintk("lockd: request from %s\n",
				svc_print_addr(rqstp, buf, sizeof(buf)));

		svc_process(rqstp);
	}
	flush_signals(current);
	if (nlmsvc_ops)
		nlmsvc_invalidate_all();
	nlm_shutdown_hosts();
	cancel_delayed_work_sync(&ln->grace_period_end);
	locks_end_grace(&ln->lockd_manager);
	return 0;
}
예제 #22
0
파일: udpcli.c 프로젝트: passedaway/module
static int _udpcli_thread_func(void *args)
{
	char buf[128] = "hello,world";
	int ret= 0;

	/* in kthread_create, it blocks all signal. so open it at here */
	allow_signal(SIGKILL);
	allow_signal(SIGTERM);

	if( -1 == sock_udpcli_connect_srv(udpcli_sock, "172.20.1.35", 8080) )
	{
		printk("error: connect to server error\n");
		goto out;
	}
	_udpcli_running  = 1;
	set_current_state(TASK_INTERRUPTIBLE);

	while( !kthread_should_stop() && !signal_pending(current) )
	{
#if 0
		if( -1 == sock_write(udpcli_sock, buf, sizeof(buf), NULL) )
		{
			printk("error: cannot send message\n");
			goto out;
		}
#endif

		if ( 0 < (ret = sock_read(udpcli_sock, buf, sizeof(buf), NULL)) )
		{
			printk("%s: recv len=%d %s\n", __FUNCTION__, ret, buf);
		}else{
			printk("%s: recv error\n", __FUNCTION__);
		}
		ssleep(1);
	}

out:
	_udpcli_running  = 0;
	printk("%s: exit\n", __FUNCTION__);
	return 0;
}
예제 #23
0
void ral_task_customize(
	IN KTHREAD *pTask)
{
	RTBT_OS_TASK *pOSTask = (RTBT_OS_TASK *)pTask->pOSThread;

	
#ifndef KTHREAD_SUPPORT
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
	daemonize((PSTRING)&pOSTask->taskName[0]);

	allow_signal(SIGTERM);
	allow_signal(SIGKILL);
	current->flags |= PF_NOFREEZE;
#else
	unsigned long flags;

	daemonize();
	reparent_to_init();
	strcpy(current->comm, &pOSTask->taskName[0]);

	siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));	
	
	/* Allow interception of SIGKILL only
	 * Don't allow other signals to interrupt the transmission */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
	spin_lock_irqsave(&current->sigmask_lock, flags);
	flush_signals(current);
	recalc_sigpending(current);
	spin_unlock_irqrestore(&current->sigmask_lock, flags);
#endif
#endif
	
	RTMP_GET_OS_PID(pOSTask->taskPID, current->pid);

    /* signal that we've started the thread */
	complete(&pOSTask->taskComplete);
#endif
}
예제 #24
0
/***************************************************
* Function: ThreadProc
***************************************************/
static int ThreadProc(
    IN		void *args)
{
    struct VL_thread_t *to_p = (struct VL_thread_t *)args;


    /* allow sending this signal */
    allow_signal(SIGKILL);
    to_p->res = to_p->func(to_p->func_ctx);

    up(&to_p->sync);

    return to_p->res;
}
예제 #25
0
INT RTUSBCmdThread(
    IN void * Context)
{
	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER)Context;

//2007/12/11:KH modified to fix compiled failed
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
	daemonize();
#else
	daemonize("rt73");
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
	allow_signal(SIGTERM);
#endif
	current->flags |= PF_NOFREEZE;
	/* signal that we've started the thread */
	complete(&(pAd->CmdThreadNotify));

	while (1)	
	{		
		int status;				
		status = down_interruptible(&(pAd->RTUSBCmd_semaphore));		
		if (status != 0)			
			continue;				

		if (RTUSBCmd_kill)
			break;
		pAd->CmdHandlerIsRunning=TRUE;
		CMDHandler(pAd);	
		pAd->CmdHandlerIsRunning=FALSE;
	}

	/* notify the exit routine that we're actually exiting now 
	 *
	 * complete()/wait_for_completion() is similar to up()/down(),
	 * except that complete() is safe in the case where the structure
	 * is getting deleted in a parallel mode of execution (i.e. just
	 * after the down() -- that's necessary for the thread-shutdown
	 * case.
	 *
	 * complete_and_exit() goes even further than this -- it is safe in
	 * the case that the thread of the caller is going away (not just
	 * the structure) -- this is necessary for the module-remove case.
	 * This is important in preemption kernels, which transfer the flow
	 * of execution immediately upon a complete().
	 */
	complete_and_exit (&pAd->CmdThreadNotify, 0);
	DBGPRINT(RT_DEBUG_TRACE, "<---RTUSBCmdThread\n");

}
예제 #26
0
int thread_fn1(void *dummy) 
{
	int j;
	allow_signal(SIGKILL);
	for (j = 0; j < 2; j++) 
	{
		printk("Entering in a Lock\n");
		spin_lock(&my_lock);
		while (i == 0);
		spin_unlock(&my_lock);
		printk("Out of spin lock\n");
	}
	thread1 = NULL;
	do_exit(0);
}
예제 #27
0
int SysSetThreadName(const char *name) 
{
	SysLockKernel();
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,61)
        daemonize();
        sigfillset(&current->blocked);
        sprintf(current->comm, "%s", name);
#else
        daemonize("%s", name);
        allow_signal(SIGTERM);
#endif
        siginitsetinv(&current->blocked, sigmask(SIGKILL)|sigmask(SIGINT)|                        sigmask(SIGTERM));
        SysUnlockKernel();

	return 0;
}
예제 #28
0
파일: thread_buggy.c 프로젝트: sysplay/bbb
// Function executed by kernel thread
static int thread_fn(void *unused)
{
	// Allow the SIGKILL signal
	allow_signal(SIGKILL);
	while (!kthread_should_stop())
	{
		printk(KERN_INFO "Thread Running\n");
		ssleep(5);
		if (signal_pending(current))
			break;
	}
	printk(KERN_INFO "Thread Stopping\n");
	thread_st = NULL;
	thread_st->state = 0;
	do_exit(0);
}
예제 #29
0
static int thread_sample(void *data)
{
	int ret = 0;
	allow_signal(SIGINT);
	while (!kthread_should_stop()) {
		ret = wait_for_completion_interruptible(&completion);
		if (ret == -ERESTARTSYS) {
			pr_debug("interrupted\n");
			return -EINTR;
		}
		/*
		   perform here a useful work in scheduler context
		 */
	}
	return ret;
}
예제 #30
0
static void gannet_recvloop(void)
{
	int size;
	int bufsize = 1600;
	unsigned char buf[bufsize + 1];
	/* Kernal 3.0 Changes Start */
	static DEFINE_MUTEX(ker_lock_mutex);

	/* kernel thread initialization */
	// lock_kernel(); ==> Commenting this line since in Kernal 3.0 this feature has been removed.
	   mutex_lock(&ker_lock_mutex);
	/* Kernal 3.0 Changes End */


	current->flags |= PF_NOFREEZE;

	/* daemonize (take care with signals,
	   after daemonize they are disabled) */
	daemonize(MODULE_NAME);
	allow_signal(SIGKILL);
	/* Kernal 3.0 Changes Start */
	// unlock_kernel(); ==> Commenting this line since in Kernal 3.0 this feature has been removed
	  mutex_unlock(&ker_lock_mutex);
    /* Kernal 3.0 Changes End */

	/* main loop */
	while (!gthreadquit) {
		memset(&buf, 0, bufsize + 1);
		size = ksocket_receive(gthread->priv->rx_sock,
					   &gthread->priv->rx_addr,
					   buf, bufsize);

		if (signal_pending(current))
			break;

		if (size < 0) {
			printk(KERN_ERR MODULE_NAME
				   "gannet: error getting datagram, "
				   "sock_recvmsg error = %d\n", size);
		} else {
			/* send to kernel */
			rx(buf, size);
		}
	}

	printk(KERN_INFO "gannet thread exit\n");
}