qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Jiri Slaby <jslaby@suse.cz>, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v2 1/1] pci-host: add educational driver
Date: Fri, 05 Dec 2014 13:07:02 +0100	[thread overview]
Message-ID: <54819FE6.1080800@redhat.com> (raw)
In-Reply-To: <54819ACB.1080204@suse.cz>



On 05/12/2014 12:45, Jiri Slaby wrote:
> On 12/05/2014, 11:35 AM, Paolo Bonzini wrote:
>> Hi Jirka,
>>
>> because this is supposed to be a poster of good QEMU practices, the
>> review is going to be a bit picky.  Most comments are trivial to apply.
> 
> Hi, OK :).
> 
>>> --- /dev/null
>>> +++ b/hw/misc/edu.c
>>> @@ -0,0 +1,351 @@
> ...
>>> +static void edu_dma_timer(void *opaque)
>>> +{
>>> +	EduState *edu = opaque;
>>
>> If you use timer_init, you might as well use container_of here.
> 
> But how? I do not have the timer as a param, right?

If you use timer_init, you can choose whether to pass the Timer or
EduState as the opaque.  With timer_new, you have to pass the opaque.
Any of the two can do.

>>> +static uint64_t edu_mmio_read(void *opaque, hwaddr addr, unsigned size)
>>> +{
>>> +    EduState *edu = opaque;
>>> +    uint64_t val = ~0ULL;
>>> +
>>> +    if (size != 4)
>>> +	return val;
>>> +
>>> +    switch (addr) {
>>> +    case 0x00:
>>> +	val = 0x010000edu;
>>> +	break;
>>> +    case 0x04:
>>> +	val = edu->addr4;
>>> +	break;
>>> +    case 0x08:
>>> +	qemu_mutex_lock(&edu->thr_mutex);
>>> +	val = edu->fact;
>>> +	qemu_mutex_unlock(&edu->thr_mutex);
>>
>> No need for the mutex.
> 
> But threads, as you wrote are not protected by the big lock. So
> shouldn't this be at least atomic_get()?

Yes, you can use atomic_read(), same kernel ACCESS_ONCE.

I was a bit confused because you had barriers, and tried to understand
what you meant since you had a smp_rmb() but no matching smp_wmb().  I
think both fact and status writes need to be under the mutex.  As to reads:

- either you put reads under the mutex

- or you put reads outside the mutex, and then you have to use barriers.


>>> +static void edu_mmio_write(void *opaque, hwaddr addr, uint64_t val,
>>> +		unsigned size)
>>> +{
>>> +    EduState *edu = opaque;
>>> +
>>> +    if (addr < 0x80 && size != 4)
>>> +	return;
>>> +
>>> +    if (addr >= 0x80 && size != 4 && size != 8)
>>> +	return;
>>> +
>>> +    switch (addr) {
>>> +    case 0x04:
>>> +	edu->addr4 = ~val;
>>> +	break;
>>> +    case 0x08:
>>> +	if (edu->status & EDU_STATUS_COMPUTING)
>>> +		break;
>>> +	edu->status |= EDU_STATUS_COMPUTING;
>>
>> atomic_or(&edu->status, EDU_STATUS_COMPUTING);
>>
>>> +	qemu_mutex_lock(&edu->thr_mutex);
>>> +	edu->fact = val;
>>
>> Probably the write should be ignored if edu->status has the computing
>> bit set, otherwise if you write 4 and 5 in rapid succession you will end
>> up with 24! in edu->fact.
> 
> But it is, AFAICS above?

Oops.  I was only looking inside the critical section.  Does it have to
be checked inside the mutex, in fact?

Also, the qemu_cond_wait has to be protected with

    while ((edu->status & EDU_STATUS_COMPUTING) == 0 && !edu->stopping)

to avoid problems with spurious wakeups.

>>> +	qemu_cond_signal(&edu->thr_cond);
>>> +	qemu_mutex_unlock(&edu->thr_mutex);
>>> +	break;
>>
>> If you add the above suggestion to use interrupts, you can do:
>>
>>     case 0x24:
>>         if (val & EDU_STATUS_FACT_IRQ)
>>             atomic_or(&edu->status, EDU_STATUS_FACT_IRQ);
>>         else
>>             atomic_and(&edu->status, ~EDU_STATUS_FACT_IRQ);
>>         break;
>>
>> to leave bit 0 untouched.
> 
> Did you mean case 0x20?

Yes, sorry.

>>> +    case 0x60:
>>> +	edu->irq_status |= val;
>>> +	pci_set_irq(&edu->pdev, 1);
>>
>> Should not set irq if edu->irq_status is zero.
> 
> I don't understand this. 0x60 is supposed to raise interrupts mostly
> when edu->irq_status is 0.

But if you write zero, i.e. edu->irq_status is zero after the OR, it
shouldn't raise a spurious interrupt, should it?

Paolo

  reply	other threads:[~2014-12-05 12:07 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-10 11:37 [Qemu-devel] [patch] qemu educational device Jiri Slaby
2014-10-10 11:49 ` Paolo Bonzini
2014-10-10 12:09   ` [Qemu-devel] [PATCH 1/1] pci-host: add educational driver Jiri Slaby
2014-10-10 14:54     ` Claudio Fontana
2014-10-13  8:32       ` Jiri Slaby
2014-10-13 13:02         ` Paolo Bonzini
2014-10-13 13:00     ` Paolo Bonzini
2014-12-03 15:11       ` Jiri Slaby
2014-12-03 15:18         ` Paolo Bonzini
2014-12-05  9:52     ` [Qemu-devel] [PATCH v2 " Jiri Slaby
2014-12-05  9:53       ` Jiri Slaby
2014-12-05 10:35       ` Paolo Bonzini
2014-12-05 11:45         ` Jiri Slaby
2014-12-05 12:07           ` Paolo Bonzini [this message]
2014-12-05  9:54     ` [Qemu-devel] [PATCH v3 " Jiri Slaby

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=54819FE6.1080800@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=jslaby@suse.cz \
    --cc=qemu-devel@nongnu.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).