All of lore.kernel.org
 help / color / mirror / Atom feed
From: Amos Kong <akong@redhat.com>
To: Amit Shah <amit.shah@redhat.com>
Cc: herbert@gondor.apana.org.au, kvm@vger.kernel.org,
	virtualization@lists.linux-foundation.org
Subject: Re: RFC virtio-rng: fail to read sysfs of a busy device
Date: Wed, 10 Sep 2014 14:49:38 +0800	[thread overview]
Message-ID: <20140910064938.GB30285@zen.redhat.com> (raw)
In-Reply-To: <20140910055212.GB29832@grmbl.mre>

On Wed, Sep 10, 2014 at 11:22:12AM +0530, Amit Shah wrote:
> On (Tue) 09 Sep 2014 [23:23:07], Amos Kong wrote:
> > (Resend to fix the subject)
> > 
> > Hi Amit, Rusty
> > 
> > RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1127062
> > steps:
> > - Read random data by 'dd if=/dev/hwrng of=/dev/null' in guest
> > - check sysfs files in the same time, 'cat /sys/class/misc/hw_random/rng_*'
> > 
> > Result: cat process will get stuck, it will return if we kill dd process.
> 
> How common is it going to be to have a long-running 'dd' process on
> /dev/hwrng?

Not a common usage, but we have this strict testing.
 
> Also, with the new khwrng thread, reading from /dev/hwrng isn't
> required -- just use /dev/random?

Yes.
 
> (This doesn't mean we shouldn't fix the issue here...)

Completely agree :-)
 
> > We have some static variables (eg, current_rng, data_avail, etc) in hw_random/core.c,
> > they are protected by rng_mutex. I try to workaround this issue by undelay(100)
> > after mutex_unlock() in rng_dev_read(). This gives chance for hwrng_attr_*_show()
> > to get mutex.
> > 
> > This patch also contains some cleanup, moving some code out of mutex
> > protection.
> > 
> > Do you have some suggestion? Thanks.
> > 
> > 
> > diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
> > index aa30a25..fa69020 100644
> > --- a/drivers/char/hw_random/core.c
> > +++ b/drivers/char/hw_random/core.c
> > @@ -194,6 +194,7 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf,
> >  		}
> >  
> >  		mutex_unlock(&rng_mutex);
> > +		udelay(100);
> 
> We have a need_resched() right below.  Why doesn't that work?

need_resched() is giving chance for userspace to 
 
> >  		if (need_resched())

It never success in my debugging.

If we remove this check and always call schedule_timeout_interruptible(1),
problem also disappears.

diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index aa30a25..263a370 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -195,8 +195,7 @@ static ssize_t rng_dev_read(struct file *filp,
char __user *buf,
 
                mutex_unlock(&rng_mutex);
 
-               if (need_resched())
-                       schedule_timeout_interruptible(1);
+               schedule_timeout_interruptible(1);
 
                if (signal_pending(current)) {
                        err = -ERESTARTSYS;

> >  			schedule_timeout_interruptible(1);
> > @@ -233,10 +234,10 @@ static ssize_t hwrng_attr_current_store(struct device *dev,
> >  	int err;
> >  	struct hwrng *rng;
 
> The following hunk doesn't work:
> 
> > +	err = -ENODEV;
> >  	err = mutex_lock_interruptible(&rng_mutex);
> 
> err is being set to another value in the next line!
> 
> >  	if (err)
> >  		return -ERESTARTSYS;
> > -	err = -ENODEV;
> 
> And all usage of err below now won't have -ENODEV but some other value.

Oops!
 
> >  	list_for_each_entry(rng, &rng_list, list) {
> >  		if (strcmp(rng->name, buf) == 0) {
> >  			if (rng == current_rng) {
> > @@ -270,8 +271,8 @@ static ssize_t hwrng_attr_current_show(struct device *dev,
> >  		return -ERESTARTSYS;
> >  	if (current_rng)
> >  		name = current_rng->name;
> > -	ret = snprintf(buf, PAGE_SIZE, "%s\n", name);
> >  	mutex_unlock(&rng_mutex);
> > +	ret = snprintf(buf, PAGE_SIZE, "%s\n", name);
> 
> This looks OK...
> 
> >  
> >  	return ret;
> >  }
> > @@ -284,19 +285,19 @@ static ssize_t hwrng_attr_available_show(struct device *dev,
> >  	ssize_t ret = 0;
> >  	struct hwrng *rng;
> >  
> > +	buf[0] = '\0';
> >  	err = mutex_lock_interruptible(&rng_mutex);
> >  	if (err)
> >  		return -ERESTARTSYS;
> >
> > -	buf[0] = '\0';
> >  	list_for_each_entry(rng, &rng_list, list) {
> >  		strncat(buf, rng->name, PAGE_SIZE - ret - 1);
> >  		ret += strlen(rng->name);
> >  		strncat(buf, " ", PAGE_SIZE - ret - 1);
> >  		ret++;
> >  	}
> > +	mutex_unlock(&rng_mutex);
> >  	strncat(buf, "\n", PAGE_SIZE - ret - 1);
> >  	ret++;
> > -	mutex_unlock(&rng_mutex);
> 
> But this isn't resulting in savings; the majority of the time is being
> spent in the for loop, and that writes to the buffer.

Right
 
> BTW I don't expect strcat'ing to the buf in each of these scenarios is
> a long operation, so this reworking doesn't strike to me as something
> we should pursue.
> 
> 		Amit

-- 
			Amos.

  reply	other threads:[~2014-09-10  6:49 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-09 15:18 mutex Amos Kong
2014-09-09 15:23 ` RFC virtio-rng: fail to read sysfs of a busy device Amos Kong
2014-09-10  5:52   ` Amit Shah
2014-09-10  6:49     ` Amos Kong [this message]
2014-09-10  7:32       ` Amos Kong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140910064938.GB30285@zen.redhat.com \
    --to=akong@redhat.com \
    --cc=amit.shah@redhat.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=kvm@vger.kernel.org \
    --cc=virtualization@lists.linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.