On Sat, Feb 23, 2008 at 11:14:51AM -0800, Anthony Brock wrote:
> My instance has the follow on the file system:
> 
> # ls -lA /dev/*rand*
> crw-rw-rw- 1 root root 1, 8 2008-02-11 11:43 /dev/random
> crw-rw-rw- 1 root root 1, 9 2008-02-23 10:06 /dev/urandom
> #
> 
> Is it possible that recent kernel versions are having issues with
> /dev/random? Any ideas on what would cause this behavior, or an I dealing
> with a known issue/misconfiguration?

See if the patch below helps...

                                Jeff

-- 
Work email - jdike at linux dot intel dot com

Index: linux-2.6.22/arch/um/drivers/random.c
===================================================================
--- linux-2.6.22.orig/arch/um/drivers/random.c  2008-01-17 12:51:06.000000000 
-0500
+++ linux-2.6.22/arch/um/drivers/random.c       2008-01-29 10:49:16.000000000 
-0500
@@ -8,16 +8,18 @@
 #include <linux/sched.h>
 #include <linux/module.h>
 #include <linux/fs.h>
+#include <linux/interrupt.h>
 #include <linux/miscdevice.h>
 #include <linux/delay.h>
 #include <asm/uaccess.h>
+#include "irq_kern.h"
 #include "os.h"
 
 /*
  * core module and version information
  */
 #define RNG_VERSION "1.0.0"
-#define RNG_MODULE_NAME "random"
+#define RNG_MODULE_NAME "hw_random"
 
 #define RNG_MISCDEV_MINOR              183 /* official */
 
@@ -26,6 +28,7 @@
  * protects against a module being loaded twice at the same time.
  */
 static int random_fd = -1;
+static DECLARE_WAIT_QUEUE_HEAD(host_read_wait);
 
 static int rng_dev_open (struct inode *inode, struct file *filp)
 {
@@ -38,6 +41,8 @@ static int rng_dev_open (struct inode *i
        return 0;
 }
 
+static atomic_t host_sleep_count = ATOMIC_INIT(0);
+
 static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
                              loff_t * offp)
 {
@@ -60,11 +65,26 @@ static ssize_t rng_dev_read (struct file
                         }
                 }
                 else if(n == -EAGAIN){
+                       DECLARE_WAITQUEUE(wait, current);
+
                         if (filp->f_flags & O_NONBLOCK)
                                 return ret ? : -EAGAIN;
 
-                        if(need_resched())
-                                schedule_timeout_interruptible(1);
+                       atomic_inc(&host_sleep_count);
+                       reactivate_fd(random_fd, RANDOM_IRQ);
+                       add_sigio_fd(random_fd);
+
+                       add_wait_queue(&host_read_wait, &wait);
+                       set_task_state(current, TASK_INTERRUPTIBLE);
+
+                       schedule();
+                       set_task_state(current, TASK_RUNNING);
+                       remove_wait_queue(&host_read_wait, &wait);
+
+                       if(atomic_dec_and_test(&host_sleep_count)){
+                               ignore_sigio_fd(random_fd);
+                               deactivate_fd(random_fd, RANDOM_IRQ);
+                       }
                 }
                 else return n;
                if (signal_pending (current))
@@ -86,6 +106,14 @@ static struct miscdevice rng_miscdev = {
        &rng_chrdev_ops,
 };
 
+static irqreturn_t random_interrupt(int irq, void *data)
+{
+       wake_up(&host_read_wait);
+
+       return IRQ_HANDLED;
+}
+
+extern void sigio_broken(int fd, int read);
 /*
  * rng_init - initialize RNG module
  */
@@ -99,10 +127,14 @@ static int __init rng_init (void)
 
         random_fd = err;
 
-        err = os_set_fd_block(random_fd, 0);
+       err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt,
+                            IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "random",
+                            NULL);
         if(err)
                goto err_out_cleanup_hw;
 
+       sigio_broken(random_fd, 1);
+
        err = misc_register (&rng_miscdev);
        if (err) {
                printk (KERN_ERR RNG_MODULE_NAME ": misc device register 
failed\n");
@@ -113,6 +145,7 @@ static int __init rng_init (void)
         return err;
 
  err_out_cleanup_hw:
+       os_close_file(random_fd);
         random_fd = -1;
         goto out;
 }
@@ -122,6 +155,7 @@ static int __init rng_init (void)
  */
 static void __exit rng_cleanup (void)
 {
+       os_close_file(random_fd);
        misc_deregister (&rng_miscdev);
 }
 
Index: linux-2.6.22/arch/um/os-Linux/sigio.c
===================================================================
--- linux-2.6.22.orig/arch/um/os-Linux/sigio.c  2008-01-17 12:51:06.000000000 
-0500
+++ linux-2.6.22/arch/um/os-Linux/sigio.c       2008-01-21 16:32:44.000000000 
-0500
@@ -338,20 +338,10 @@ out_close1:
        close(l_write_sigio_fds[1]);
 }
 
-/* Changed during early boot */
-static int pty_output_sigio = 0;
-static int pty_close_sigio = 0;
-
-void maybe_sigio_broken(int fd, int read)
+void sigio_broken(int fd, int read)
 {
        int err;
 
-       if (!isatty(fd))
-               return;
-
-       if ((read || pty_output_sigio) && (!read || pty_close_sigio))
-               return;
-
        write_sigio_workaround();
 
        sigio_lock();
@@ -370,6 +360,21 @@ out:
        sigio_unlock();
 }
 
+/* Changed during early boot */
+static int pty_output_sigio = 0;
+static int pty_close_sigio = 0;
+
+void maybe_sigio_broken(int fd, int read)
+{
+       if (!isatty(fd))
+               return;
+
+       if ((read || pty_output_sigio) && (!read || pty_close_sigio))
+               return;
+
+       sigio_broken(fd, read);
+}
+
 static void sigio_cleanup(void)
 {
        if (write_sigio_pid == -1)
Index: linux-2.6.22/include/asm-um/irq.h
===================================================================
--- linux-2.6.22.orig/include/asm-um/irq.h      2008-01-18 12:53:08.000000000 
-0500
+++ linux-2.6.22/include/asm-um/irq.h   2008-01-21 16:33:50.000000000 -0500
@@ -15,8 +15,9 @@
 #define SIGIO_WRITE_IRQ        11
 #define TELNETD_IRQ            12
 #define XTERM_IRQ              13
+#define RANDOM_IRQ             14
 
-#define LAST_IRQ XTERM_IRQ
+#define LAST_IRQ RANDOM_IRQ
 #define NR_IRQS (LAST_IRQ + 1)
 
 #endif

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
User-mode-linux-user mailing list
User-mode-linux-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-user

Reply via email to