From nobody@FreeBSD.org  Thu Aug 30 12:21:14 2001
Return-Path: <nobody@FreeBSD.org>
Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21])
	by hub.freebsd.org (Postfix) with ESMTP id 4B27F37B408
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 30 Aug 2001 12:21:14 -0700 (PDT)
	(envelope-from nobody@FreeBSD.org)
Received: (from nobody@localhost)
	by freefall.freebsd.org (8.11.4/8.11.4) id f7UJJou35676;
	Thu, 30 Aug 2001 12:19:50 -0700 (PDT)
	(envelope-from nobody)
Message-Id: <200108301919.f7UJJou35676@freefall.freebsd.org>
Date: Thu, 30 Aug 2001 12:19:50 -0700 (PDT)
From: Rob Phillips <rob@netrake.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Using /usr/share/examples/kld/cdev, testcdev fails when compiled w/ -pthread
X-Send-Pr-Version: www-1.0

>Number:         30223
>Category:       conf
>Synopsis:       [patch] Using /usr/share/examples/kld/cdev, testcdev fails when compiled w/ -pthread
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Aug 30 12:30:01 PDT 2001
>Closed-Date:    Wed Mar 07 21:19:44 GMT 2007
>Last-Modified:  Wed Mar 07 21:19:44 GMT 2007
>Originator:     Rob Phillips
>Release:        4.3-STABLE
>Organization:
Netrake Corporation
>Environment:
FreeBSD nrclient-136 4.3-RELEASE FreeBSD 4.3-RELEASE #0: sat Apr 21  10:54:49 GMT 2001     jkh@narf.osd.bsdi.com:/usr/src/sys/compile/GENERIC  i386
>Description:
I'm working on writing a KLD device driver that interacts with some
pthread-ed code, and I'm running into problems.  To make sure it wasn't
my code, I took the example code from /usr/share/examples/kld/cdev and
compiled it as-is.  This worked fine.  However, when I added the line:

   COPTS= -pthread

to the Makefile for the testcdev code, it stops working.  The device
driver records a seeminingly infinite loop of write() calls, rather than
the single write call you normally get.  It also records an unknown (to
me) ioctl that isn't there when you don't use threads.

Is this an error with the threads, the device driver, or something else?
>How-To-Repeat:
Change /usr/share/examples/kld/cdev/test/Makefile to include:

   COPTS= -pthread

It is not necessary to do any changes to the C file.  Recompile and then
run the testcdev program (after loading the cdev driver).
>Fix:

>Release-Note:
>Audit-Trail:

From: k Macy <kip_macy@yahoo.com>
To: freebsd-gnats-submit@FreeBSD.org, rob@netrake.com
Cc:  
Subject: Re: kern/30223: Using /usr/share/examples/kld/cdev, testcdev fails when compiled w/ -pthread
Date: Sun, 6 Jan 2002 20:26:23 -0800 (PST)

 This isn't a bug in the threads library, it is a bug
 in the driver :
 
 /*
  * mydev_write takes in a character string and saves it
  * to buf for later accessing.
  */
 int
 mydev_write(dev_t dev, struct uio *uio, int ioflag)
 {
     int err = 0;
 
     printf("mydev_write: dev_t=%d, uio=%p, ioflag=%d\n",
         dev2udev(dev), uio, ioflag);
 
     err = copyinstr(uio->uio_iov->iov_base, &buf, 512, &len);
     if (err != 0) {
         printf("Write to \"cdev\" failed.\n");
     }
     return(err);
 }
 
 if err is 0 it mydev_write should be returning len, the 
 number of bytes copied.
 
 It isn't returning because the thread library does a 
 non-blocking write and simulates a blocking write by 
 doing writes piecemeal:
 
                   /*
                    * Loop while no error occurs and until the expected number
                    * of bytes are written if performing a blocking write:
                    */
                   while (ret == 0) {
                           /* Perform a non-blocking write syscall: */
                           n = __sys_write(fd, buf + num, nbytes - num);
 
 sys_write is returning 0 so it keeps on writing the
 string over and over again.
 write(5,0x804988c,14)                            = 0
 (0x0)
 poll(0x8059000,0x1,0x0)                          = 1
 (0x1)
 write(5,0x804988c,14)                            = 0
 (0x0)
 poll(0x8059000,0x1,0x0)                          = 1
 (0x1)
 
 The following patch will make the driver work:
 > diff -Naur cdev.c.bak cdev.c
 --- cdev.c.bak  Sun Jan  6 18:54:54 2002
 +++ cdev.c      Sun Jan  6 20:03:51 2002
 @@ -149,16 +149,14 @@
  int
  mydev_write(dev_t dev, struct uio *uio, int ioflag)
  {
 -    int err = 0;
 +    int towrite = 0;
  
      printf("mydev_write: dev_t=%d, uio=%p, ioflag=%d\n",
         dev2udev(dev), uio, ioflag);
  
 -    err = copyinstr(uio->uio_iov->iov_base, &buf, 512, &len);
 -    if (err != 0) {
 -       printf("Write to \"cdev\" failed.\n");
 -    }
 -    return(err);
 +    towrite = (min(uio->uio_resid, sizeof(buf)));
 +    len = towrite;
 +    return(uiomove(buf, towrite, uio));
  }
  
  /*
 
 Although the ioctl is still getting called incorrectly
 twice when compiled with pthread:
 once after open:
 open("/dev/cdev",0x2,00)                         = 5
 (0x5)
 fcntl(0x5,0x3,0x0)                               = 2
 (0x2)
 fcntl(0x5,0x4,0x6)                              
 ERR#22 'Invalid argument'
 
 and once before exit:
 fcntl(0x5,0x4,0x2)                              
 ERR#22 'Invalid argument'
 exit(0x0)                                      
 process exit, rval = 0
 
 What is doing is setting the nonblocking flag on open,
 and unsetting on exit and this trivial driver doesn't
 support having flags set on it:
         /*
          * Enter a loop to set all file descriptors to blocking
          * if they were not created as non-blocking:
          */
         for (i = 0; i < _thread_dtablesize; i++) {
                 /* Check if this file descriptor is in use: */
                 if (_thread_fd_table[i] != NULL &&
                         !(_thread_fd_table[i]->flags & O_NONBLOCK)) {
                         /* Get the current flags: */
                         flags = _thread_sys_fcntl(i, F_GETFL, NULL);
                         /* Clear the nonblocking file descriptor flag: */
                         _thread_sys_fcntl(i, F_SETFL, flags & ~O_NONBLOCK);
                 }
         }
 
         /* Call the _exit syscall: */
         _thread_sys__exit(status);
 
 
 
 
 __________________________________________________
 Do You Yahoo!?
 Send FREE video emails in Yahoo! Mail!
 http://promo.yahoo.com/videomail/
State-Changed-From-To: open->closed 
State-Changed-By: remko 
State-Changed-When: Wed Mar 7 21:19:43 UTC 2007 
State-Changed-Why:  
It was mentioned that this was a bug in the kld code itself (from the 
submitter), no feedback after that so I am assuming this was correct. 
Please prove me my mistake if needed... 

http://www.freebsd.org/cgi/query-pr.cgi?pr=30223 
>Unformatted:
