All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] Guest application reading from pl011 without device driver
@ 2017-03-21 16:32 Jiahuan Zhang
  2017-03-21 16:39 ` Peter Maydell
  0 siblings, 1 reply; 26+ messages in thread
From: Jiahuan Zhang @ 2017-03-21 16:32 UTC (permalink / raw)
  To: qemu-devel

Dear QEMU developers,

I am trying to read streaming data from a serial device by pointing to the
data register. The input data for the serial device is a string, whose
length is larger than the receiving fifo (I am using pl011). Ths input is
done by ReadFile() since my host is Win 7;

Now the guest application is able to receive the data, if the data size is
smaller than the fifo size, 16 bytes. But the communication fails when
receiving larger data.

I found the serial device is always trying to receive all the data when
ReadFile() is running, then start reading. Even if the fifo is full, the
_can_receive function still keeps polling if the data is larger than 16
bytes.

I try to write the interrupt in the guest application to force the serial
device to start reading right after the fifo is not empty. However, my
programming is too poor to work.

Am I on the right way to figure it out?
Looking forwards to your suggestion.

Best,
Huan

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-21 16:32 [Qemu-devel] Guest application reading from pl011 without device driver Jiahuan Zhang
@ 2017-03-21 16:39 ` Peter Maydell
  2017-03-21 16:47   ` Jiahuan Zhang
  0 siblings, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2017-03-21 16:39 UTC (permalink / raw)
  To: Jiahuan Zhang; +Cc: QEMU Developers

On 21 March 2017 at 16:32, Jiahuan Zhang <jiahuanzhang90@gmail.com> wrote:
> I found the serial device is always trying to receive all the data when
> ReadFile() is running, then start reading. Even if the fifo is full, the
> _can_receive function still keeps polling if the data is larger than 16
> bytes.

pl011_can_receive() is:

static int pl011_can_receive(void *opaque)
{
    PL011State *s = (PL011State *)opaque;
    int r;

    if (s->lcr & 0x10) {
        r = s->read_count < 16;
    } else {
        r = s->read_count < 1;
    }
    trace_pl011_can_receive(s->lcr, s->read_count, r);
    return r;
}

so if the FIFO fills up then it should start to return 'false',
as it is supposed to.

I'm not sure from your description what exactly is happening,
but you should probably check, for instance:
 * whether pl011_can_receive is returning false but data
   is still being fed to it
 * whether pl011_can_receive is returning true even with
   16 bytes in the fifo (hard to see how, given the code)
 * whether the fifo actually has fewer bytes in it because
   the guest is reading them
 * etc

thanks
-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-21 16:39 ` Peter Maydell
@ 2017-03-21 16:47   ` Jiahuan Zhang
  2017-03-21 16:50     ` Peter Maydell
  0 siblings, 1 reply; 26+ messages in thread
From: Jiahuan Zhang @ 2017-03-21 16:47 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

many thanks for the rapid reply!

On 21 March 2017 at 17:39, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 21 March 2017 at 16:32, Jiahuan Zhang <jiahuanzhang90@gmail.com> wrote:
> > I found the serial device is always trying to receive all the data when
> > ReadFile() is running, then start reading. Even if the fifo is full, the
> > _can_receive function still keeps polling if the data is larger than 16
> > bytes.
>
> pl011_can_receive() is:
>
> static int pl011_can_receive(void *opaque)
> {
>     PL011State *s = (PL011State *)opaque;
>     int r;
>
>     if (s->lcr & 0x10) {
>         r = s->read_count < 16;
>     } else {
>         r = s->read_count < 1;
>     }
>     trace_pl011_can_receive(s->lcr, s->read_count, r);
>     return r;
> }


> so if the FIFO fills up then it should start to return 'false',
> as it is supposed to.
>
> I'm not sure from your description what exactly is happening,
> but you should probably check, for instance:
>  * whether pl011_can_receive is returning false but data
>    is still being fed to it
>

The actual situation is, pl011_can_receive is returning false, the fifo is
full,
pl011_read does't start.
At this moment, only pl011_can_recieve is keeping returning 0.


>  * whether pl011_can_receive is returning true even with
>    16 bytes in the fifo (hard to see how, given the code)
>  * whether the fifo actually has fewer bytes in it because
>    the guest is reading them
>

No, because the guest application does't get any data.


>  * etc
>
> thanks
> -- PMM
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-21 16:47   ` Jiahuan Zhang
@ 2017-03-21 16:50     ` Peter Maydell
  2017-03-21 16:59       ` Jiahuan Zhang
  0 siblings, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2017-03-21 16:50 UTC (permalink / raw)
  To: Jiahuan Zhang; +Cc: QEMU Developers

On 21 March 2017 at 16:47, Jiahuan Zhang <jiahuanzhang90@gmail.com> wrote:
> The actual situation is, pl011_can_receive is returning false, the fifo is
> full,   pl011_read does't start.
> At this moment, only pl011_can_recieve is keeping returning 0.

OK, so the incoming data has filled up the FIFO, and the UART
is now sitting waiting for the guest to read the data...

>>  * whether pl011_can_receive is returning true even with
>>    16 bytes in the fifo (hard to see how, given the code)
>>  * whether the fifo actually has fewer bytes in it because
>>    the guest is reading them
>
>
> No, because the guest application does't get any data.

...so if the guest isn't getting any data that suggests it's
the guest code's bug (ie it is not actually reading out of
the FIFO).

thanks
-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-21 16:50     ` Peter Maydell
@ 2017-03-21 16:59       ` Jiahuan Zhang
  2017-03-21 17:10         ` Jiahuan Zhang
  2017-03-21 17:16         ` Peter Maydell
  0 siblings, 2 replies; 26+ messages in thread
From: Jiahuan Zhang @ 2017-03-21 16:59 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

On 21 March 2017 at 17:50, Peter Maydell <peter.maydell@linaro.org> wrote:

> On 21 March 2017 at 16:47, Jiahuan Zhang <jiahuanzhang90@gmail.com> wrote:
> > The actual situation is, pl011_can_receive is returning false, the fifo
> is
> > full,   pl011_read does't start.
> > At this moment, only pl011_can_recieve is keeping returning 0.
>
> OK, so the incoming data has filled up the FIFO, and the UART
> is now sitting waiting for the guest to read the data...
>

Yes. And I think the guest reading can start when the fifo is nonempty.
In the guest program, I first check the flag register, once the fifo is
nonempty,
then move on to read from the data register.

This works to read small data, smaller than 16 bytes.

>
> >>  * whether pl011_can_receive is returning true even with
> >>    16 bytes in the fifo (hard to see how, given the code)
> >>  * whether the fifo actually has fewer bytes in it because
> >>    the guest is reading them
> >
> >
> > No, because the guest application does't get any data.
>
> ...so if the guest isn't getting any data that suggests it's
> the guest code's bug (ie it is not actually reading out of
> the FIFO).
>

What I found is pl011 expects to read all the data into fifo,
though pl011_can_receive returns false.
Only when all the data is read, pl011_read can start.

>
> thanks
> -- PMM
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-21 16:59       ` Jiahuan Zhang
@ 2017-03-21 17:10         ` Jiahuan Zhang
  2017-03-21 17:16         ` Peter Maydell
  1 sibling, 0 replies; 26+ messages in thread
From: Jiahuan Zhang @ 2017-03-21 17:10 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

On 21 March 2017 at 17:59, Jiahuan Zhang <jiahuanzhang90@gmail.com> wrote:

>
>
> On 21 March 2017 at 17:50, Peter Maydell <peter.maydell@linaro.org> wrote:
>
>> On 21 March 2017 at 16:47, Jiahuan Zhang <jiahuanzhang90@gmail.com>
>> wrote:
>> > The actual situation is, pl011_can_receive is returning false, the fifo
>> is
>> > full,   pl011_read does't start.
>> > At this moment, only pl011_can_recieve is keeping returning 0.
>>
>> OK, so the incoming data has filled up the FIFO, and the UART
>> is now sitting waiting for the guest to read the data...
>>
>
> Yes. And I think the guest reading can start when the fifo is nonempty.
> In the guest program, I first check the flag register, once the fifo is
> nonempty,
> then move on to read from the data register.
>
> This works to read small data, smaller than 16 bytes.
>
>>
>> >>  * whether pl011_can_receive is returning true even with
>> >>    16 bytes in the fifo (hard to see how, given the code)
>> >>  * whether the fifo actually has fewer bytes in it because
>> >>    the guest is reading them
>> >
>> >
>> > No, because the guest application does't get any data.
>>
>> ...so if the guest isn't getting any data that suggests it's
>> the guest code's bug (ie it is not actually reading out of
>> the FIFO).
>>
>
> What I found is pl011 expects to read all the data into fifo,
> though pl011_can_receive returns false.
> Only when all the data is read, pl011_read can start.
>

The only thing I can consider about my guest application is the interrupt.
Since in pl011_put_fifo(),

*if* (s->read_count == s->read_trigger){

s->int_level |= PL011_INT_RX;

pl011_update(s);

}

I try to enable the interrupt in the guest program, but still not work.


>> thanks
>> -- PMM
>>
>
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-21 16:59       ` Jiahuan Zhang
  2017-03-21 17:10         ` Jiahuan Zhang
@ 2017-03-21 17:16         ` Peter Maydell
  2017-03-21 17:48           ` Jiahuan Zhang
  1 sibling, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2017-03-21 17:16 UTC (permalink / raw)
  To: Jiahuan Zhang; +Cc: QEMU Developers

On 21 March 2017 at 16:59, Jiahuan Zhang <jiahuanzhang90@gmail.com> wrote:
>
>
> On 21 March 2017 at 17:50, Peter Maydell <peter.maydell@linaro.org> wrote:
>>
>> On 21 March 2017 at 16:47, Jiahuan Zhang <jiahuanzhang90@gmail.com> wrote:
>> > The actual situation is, pl011_can_receive is returning false, the fifo
>> > is
>> > full,   pl011_read does't start.
>> > At this moment, only pl011_can_recieve is keeping returning 0.
>>
>> OK, so the incoming data has filled up the FIFO, and the UART
>> is now sitting waiting for the guest to read the data...
>
>
> Yes. And I think the guest reading can start when the fifo is nonempty.
> In the guest program, I first check the flag register, once the fifo is
> nonempty,
> then move on to read from the data register.

Which flag are you testing?

> What I found is pl011 expects to read all the data into fifo,
> though pl011_can_receive returns false.
> Only when all the data is read, pl011_read can start.

This doesn't make sense. If our pl011 didn't allow reads
of data before the FIFO was full then you'd see small
data not working, but large data working.

In any case our pl011_read implementation will happily
return you any data it has as long as the fifo is not
completely empty, and even if the guest buggily reads
from an empty FIFO it will return you the last character
read (this is how the h/w works, IIRC).

(This would be much easier if you actually said what your
guest code did, rather than requiring me to guess.)

thanks
-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-21 17:16         ` Peter Maydell
@ 2017-03-21 17:48           ` Jiahuan Zhang
  2017-03-21 17:55             ` Peter Maydell
  0 siblings, 1 reply; 26+ messages in thread
From: Jiahuan Zhang @ 2017-03-21 17:48 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

But what I met is that, when the receiving data is small, no data is
knocking the door of the fifo by ReadFile (), then pl011_read can starts.
When the data is large, after the fifo is full, there are still data
requesting to get into the fifo. Then the device is busy with
pl011_can_receive.

The guest program is as follows.

While (*UART_FR & PL011_RXFE); //wait until fifo not empty
for (i=0;i <16;i++){
data [i] = (unsigned char) *UART_DR; //read from the data register.
}

Best,
Huan

2017年3月21日 18:17,"Peter Maydell" <peter.maydell@linaro.org>写道:

On 21 March 2017 at 16:59, Jiahuan Zhang <jiahuanzhang90@gmail.com> wrote:
>
>
> On 21 March 2017 at 17:50, Peter Maydell <peter.maydell@linaro.org> wrote:
>>
>> On 21 March 2017 at 16:47, Jiahuan Zhang <jiahuanzhang90@gmail.com>
wrote:
>> > The actual situation is, pl011_can_receive is returning false, the fifo
>> > is
>> > full,   pl011_read does't start.
>> > At this moment, only pl011_can_recieve is keeping returning 0.
>>
>> OK, so the incoming data has filled up the FIFO, and the UART
>> is now sitting waiting for the guest to read the data...
>
>
> Yes. And I think the guest reading can start when the fifo is nonempty.
> In the guest program, I first check the flag register, once the fifo is
> nonempty,
> then move on to read from the data register.

Which flag are you testing?

> What I found is pl011 expects to read all the data into fifo,
> though pl011_can_receive returns false.
> Only when all the data is read, pl011_read can start.

This doesn't make sense. If our pl011 didn't allow reads
of data before the FIFO was full then you'd see small
data not working, but large data working.

In any case our pl011_read implementation will happily
return you any data it has as long as the fifo is not
completely empty, and even if the guest buggily reads
from an empty FIFO it will return you the last character
read (this is how the h/w works, IIRC).

(This would be much easier if you actually said what your
guest code did, rather than requiring me to guess.)

thanks
-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-21 17:48           ` Jiahuan Zhang
@ 2017-03-21 17:55             ` Peter Maydell
       [not found]               ` <CAJy91CZ4Ed-HGHLkzEc1dqQbo32d-eTE1S1ovO_ZwkDdTpkQXQ@mail.gmail.com>
  0 siblings, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2017-03-21 17:55 UTC (permalink / raw)
  To: Jiahuan Zhang; +Cc: QEMU Developers

On 21 March 2017 at 17:48, Jiahuan Zhang <jiahuanzhang90@gmail.com> wrote:
> The guest program is as follows.
>
> While (*UART_FR & PL011_RXFE); //wait until fifo not empty
> for (i=0;i <16;i++){
>    data [i] = (unsigned char) *UART_DR; //read from the data register.
> }

This is buggy. You must check RXFE every time, because
RXFE will be cleared as soon as even a single byte is
in the FIFO. It does not mean "FIFO full", it just
means "FIFO not empty".

(You should also check that you're correctly using
'volatile' or some other mechanism for ensuring that
the C compiler does not decide that it can collapse
away accesses to hardware registers because it thinks
they're just memory and won't change value.)

> But what I met is that, when the receiving data is small,
> no data is knocking the door of the fifo by ReadFile (),
> then pl011_read can starts.
> When the data is large, after the fifo is full, there are still
> data requesting to get into the fifo. Then the device is busy
> with pl011_can_receive.

Are you saying that QEMU is looping round indefinitely calling
pl011_can_receive() and never running the guest at all?
That would be a QEMU bug, but it seems unlikely or we'd have
noticed it before.

What chardev backend are you connecting to the pl011 to
feed data to it?

thanks
-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
       [not found]                 ` <CAJy91CaCV40FgSP55qWZeZgkQ=2+E8Cr7xdbu9pn5HLEo+6JJQ@mail.gmail.com>
@ 2017-03-21 18:11                   ` Jiahuan Zhang
  2017-03-21 18:28                     ` Peter Maydell
  0 siblings, 1 reply; 26+ messages in thread
From: Jiahuan Zhang @ 2017-03-21 18:11 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

2017年3月21日 18:55,"Peter Maydell" <peter.maydell@linaro.org>写道:

On 21 March 2017 at 17:48, Jiahuan Zhang <jiahuanzhang90@gmail.com> wrote:
> The guest program is as follows.
>
> While (*UART_FR & PL011_RXFE); //wait until fifo not empty
> for (i=0;i <16;i++){
>    data [i] = (unsigned char) *UART_DR; //read from the data register.
> }

This is buggy. You must check RXFE every time, because
RXFE will be cleared as soon as even a single byte is
in the FIFO. It does not mean "FIFO full", it just
means "FIFO not empty".


Yes, here I need to make sure there are real data in the fifo, or data [i]
will get null.
Do you mean that I also need to make sure fifo is not full before reading?
For example, by while(*UART_FR & RXFF); ?

What do you mean "RXFE will be cleared"?
Here RXFE is
#define PL011_RXFE   0x10

By the way, at the beginning of the guest program, I set the line control
register s->lcr = 0x70 for pl011_can_recieve.

(You should also check that you're correctly using
'volatile' or some other mechanism for ensuring that
the C compiler does not decide that it can collapse
away accesses to hardware registers because it thinks
they're just memory and won't change value.)

> But what I met is that, when the receiving data is small,
> no data is knocking the door of the fifo by ReadFile (),
> then pl011_read can starts.
> When the data is large, after the fifo is full, there are still
> data requesting to get into the fifo. Then the device is busy
> with pl011_can_receive.

Are you saying that QEMU is looping round indefinitely calling
pl011_can_receive() and never running the guest at all?


Yes, exactly when fifo is full, s->count = 16. pl011_can_recieve keeps
returning 0.
The guest program is blocked.

That would be a QEMU bug, but it seems unlikely or we'd have
noticed it before.

What chardev backend are you connecting to the pl011 to
feed data to it?


I am using a windows named pipe to get the data from a window host program,
which uses ReadFile () in char_win.c


thanks
-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-21 18:11                   ` Jiahuan Zhang
@ 2017-03-21 18:28                     ` Peter Maydell
  2017-03-21 18:33                       ` Jiahuan Zhang
  2017-03-22  8:40                       ` Paolo Bonzini
  0 siblings, 2 replies; 26+ messages in thread
From: Peter Maydell @ 2017-03-21 18:28 UTC (permalink / raw)
  To: Jiahuan Zhang; +Cc: QEMU Developers, Paolo Bonzini, Marc-André Lureau

On 21 March 2017 at 18:11, Jiahuan Zhang <jiahuanzhang90@gmail.com> wrote:
> What do you mean "RXFE will be cleared"?
> Here RXFE is
> #define PL011_RXFE   0x10

I mean that as soon as 1 byte of data is ready to read the
RXFE bit will be cleared in the FR register. So you need:

/* probably you want to actually detect EOF somehow but let's
 * just read 16 bytes
 */
for (i = 0; i < 16; i++) {
    while (*UART_FR & PL011_RXFE) {
        /* loop until data available */
    }
    /* now read 1 byte, that's all we can be certain is there */
    data[i] = *UART_DR;
    /* ...and then go back and check RXFE again */
}

>> Are you saying that QEMU is looping round indefinitely calling
>> pl011_can_receive() and never running the guest at all?
>
>
> Yes, exactly when fifo is full, s->count = 16. pl011_can_recieve keeps
> returning 0.
> The guest program is blocked.

Right, but if can_receive returns 0, then QEMU should decide
"OK, can't do anything here" and run the guest.

> I am using a windows named pipe to get the data from a window
> host program, which uses ReadFile () in char_win.c

OK, bugs in the windows-specific char backend would be
unsurprising.

I'm not entirely sure how the chardev layer works, but
at the pl011 end if we return 0 from our can_receive
function then the chardev layer should decide it has
nothing to do until the pl011 later calls
qemu_chr_fe_accept_input(), I think.

I've cc'd Paolo and Marc-André Lureau as the chardev
maintainers.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-21 18:28                     ` Peter Maydell
@ 2017-03-21 18:33                       ` Jiahuan Zhang
  2017-03-22  8:40                       ` Paolo Bonzini
  1 sibling, 0 replies; 26+ messages in thread
From: Jiahuan Zhang @ 2017-03-21 18:33 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Marc-André Lureau, Paolo Bonzini, QEMU Developers

Okay. Thank you very much.
I'll take your advice and test.
Let's see the chardev maintainers reply.

Best,
Huan

2017年3月21日 19:28,"Peter Maydell" <peter.maydell@linaro.org>写道:

> On 21 March 2017 at 18:11, Jiahuan Zhang <jiahuanzhang90@gmail.com> wrote:
> > What do you mean "RXFE will be cleared"?
> > Here RXFE is
> > #define PL011_RXFE   0x10
>
> I mean that as soon as 1 byte of data is ready to read the
> RXFE bit will be cleared in the FR register. So you need:
>
> /* probably you want to actually detect EOF somehow but let's
>  * just read 16 bytes
>  */
> for (i = 0; i < 16; i++) {
>     while (*UART_FR & PL011_RXFE) {
>         /* loop until data available */
>     }
>     /* now read 1 byte, that's all we can be certain is there */
>     data[i] = *UART_DR;
>     /* ...and then go back and check RXFE again */
> }
>
> >> Are you saying that QEMU is looping round indefinitely calling
> >> pl011_can_receive() and never running the guest at all?
> >
> >
> > Yes, exactly when fifo is full, s->count = 16. pl011_can_recieve keeps
> > returning 0.
> > The guest program is blocked.
>
> Right, but if can_receive returns 0, then QEMU should decide
> "OK, can't do anything here" and run the guest.
>
> > I am using a windows named pipe to get the data from a window
> > host program, which uses ReadFile () in char_win.c
>
> OK, bugs in the windows-specific char backend would be
> unsurprising.
>
> I'm not entirely sure how the chardev layer works, but
> at the pl011 end if we return 0 from our can_receive
> function then the chardev layer should decide it has
> nothing to do until the pl011 later calls
> qemu_chr_fe_accept_input(), I think.
>
> I've cc'd Paolo and Marc-André Lureau as the chardev
> maintainers.
>
> thanks
> -- PMM
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-21 18:28                     ` Peter Maydell
  2017-03-21 18:33                       ` Jiahuan Zhang
@ 2017-03-22  8:40                       ` Paolo Bonzini
  2017-03-22  8:48                         ` Jiahuan Zhang
  2017-03-22 11:07                         ` Peter Maydell
  1 sibling, 2 replies; 26+ messages in thread
From: Paolo Bonzini @ 2017-03-22  8:40 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Jiahuan Zhang, QEMU Developers, Marc-André Lureau


> > I am using a windows named pipe to get the data from a window
> > host program, which uses ReadFile () in char_win.c
> 
> OK, bugs in the windows-specific char backend would be
> unsurprising.
> 
> I'm not entirely sure how the chardev layer works, but
> at the pl011 end if we return 0 from our can_receive
> function then the chardev layer should decide it has
> nothing to do until the pl011 later calls
> qemu_chr_fe_accept_input(), I think.
> 
> I've cc'd Paolo and Marc-André Lureau as the chardev
> maintainers.

Windows named pipes do not support the equivalent of "select",
so it's possible that they cause a busy wait.  Try using a
TCP socket instead and see if the bug goes away.

Paolo

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-22  8:40                       ` Paolo Bonzini
@ 2017-03-22  8:48                         ` Jiahuan Zhang
  2017-03-22  9:37                           ` Paolo Bonzini
  2017-03-22 11:07                         ` Peter Maydell
  1 sibling, 1 reply; 26+ messages in thread
From: Jiahuan Zhang @ 2017-03-22  8:48 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers

On 22 March 2017 at 09:40, Paolo Bonzini <pbonzini@redhat.com> wrote:

>
> > > I am using a windows named pipe to get the data from a window
> > > host program, which uses ReadFile () in char_win.c
> >
> > OK, bugs in the windows-specific char backend would be
> > unsurprising.
> >
> > I'm not entirely sure how the chardev layer works, but
> > at the pl011 end if we return 0 from our can_receive
> > function then the chardev layer should decide it has
> > nothing to do until the pl011 later calls
> > qemu_chr_fe_accept_input(), I think.
> >
> > I've cc'd Paolo and Marc-André Lureau as the chardev
> > maintainers.
>
> Windows named pipes do not support the equivalent of "select",
> so it's possible that they cause a busy wait.  Try using a
> TCP socket instead and see if the bug goes away.
>

Hi, I am trying to use a Windows socket for serial redirection instead of
Windows named pipe.
What do you mean "the equivalent of 'select'"?


>
> Paolo
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-22  8:48                         ` Jiahuan Zhang
@ 2017-03-22  9:37                           ` Paolo Bonzini
  2017-03-22 10:28                             ` Jiahuan Zhang
  0 siblings, 1 reply; 26+ messages in thread
From: Paolo Bonzini @ 2017-03-22  9:37 UTC (permalink / raw)
  To: Jiahuan Zhang; +Cc: QEMU Developers



On 22/03/2017 09:48, Jiahuan Zhang wrote:
> 
> 
> On 22 March 2017 at 09:40, Paolo Bonzini <pbonzini@redhat.com
> <mailto:pbonzini@redhat.com>> wrote:
> 
> 
>     > > I am using a windows named pipe to get the data from a window
>     > > host program, which uses ReadFile () in char_win.c
>     >
>     > OK, bugs in the windows-specific char backend would be
>     > unsurprising.
>     >
>     > I'm not entirely sure how the chardev layer works, but
>     > at the pl011 end if we return 0 from our can_receive
>     > function then the chardev layer should decide it has
>     > nothing to do until the pl011 later calls
>     > qemu_chr_fe_accept_input(), I think.
>     >
>     > I've cc'd Paolo and Marc-André Lureau as the chardev
>     > maintainers.
> 
>     Windows named pipes do not support the equivalent of "select",
>     so it's possible that they cause a busy wait.  Try using a
>     TCP socket instead and see if the bug goes away.
> 
> 
> Hi, I am trying to use a Windows socket for serial redirection instead
> of Windows named pipe.
> What do you mean "the equivalent of 'select'"?

A function that lets a process sleep until data is available on the
socket.  The solution is to rewrite Windows chardev handling in QEMU to
use threads or overlapped I/O.

Paolo

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-22  9:37                           ` Paolo Bonzini
@ 2017-03-22 10:28                             ` Jiahuan Zhang
  2017-03-22 11:27                               ` Paolo Bonzini
  0 siblings, 1 reply; 26+ messages in thread
From: Jiahuan Zhang @ 2017-03-22 10:28 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers

On 22 March 2017 at 10:37, Paolo Bonzini <pbonzini@redhat.com> wrote:

>
>
> On 22/03/2017 09:48, Jiahuan Zhang wrote:
> >
> >
> > On 22 March 2017 at 09:40, Paolo Bonzini <pbonzini@redhat.com
> > <mailto:pbonzini@redhat.com>> wrote:
> >
> >
> >     > > I am using a windows named pipe to get the data from a window
> >     > > host program, which uses ReadFile () in char_win.c
> >     >
> >     > OK, bugs in the windows-specific char backend would be
> >     > unsurprising.
> >     >
> >     > I'm not entirely sure how the chardev layer works, but
> >     > at the pl011 end if we return 0 from our can_receive
> >     > function then the chardev layer should decide it has
> >     > nothing to do until the pl011 later calls
> >     > qemu_chr_fe_accept_input(), I think.
> >     >
> >     > I've cc'd Paolo and Marc-André Lureau as the chardev
> >     > maintainers.
> >
> >     Windows named pipes do not support the equivalent of "select",
> >     so it's possible that they cause a busy wait.  Try using a
> >     TCP socket instead and see if the bug goes away.
> >
> >
> > Hi, I am trying to use a Windows socket for serial redirection instead
> > of Windows named pipe.
> > What do you mean "the equivalent of 'select'"?
>
> A function that lets a process sleep until data is available on the
> socket.  The solution is to rewrite Windows chardev handling in QEMU to
> use threads or overlapped I/O.
>
> Yes, socket is working well. Will you add the "select" to pipe
implementation?
Or shall I look into it and fix? Since in my case, I prefer windows pipe to
socket.
But if I do, definitly, I will spend much more effort than you, the experts.


> Paolo
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-22  8:40                       ` Paolo Bonzini
  2017-03-22  8:48                         ` Jiahuan Zhang
@ 2017-03-22 11:07                         ` Peter Maydell
  2017-03-22 11:33                           ` Paolo Bonzini
  1 sibling, 1 reply; 26+ messages in thread
From: Peter Maydell @ 2017-03-22 11:07 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Jiahuan Zhang, QEMU Developers, Marc-André Lureau

On 22 March 2017 at 08:40, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>> > I am using a windows named pipe to get the data from a window
>> > host program, which uses ReadFile () in char_win.c
>>
>> OK, bugs in the windows-specific char backend would be
>> unsurprising.
>>
>> I'm not entirely sure how the chardev layer works, but
>> at the pl011 end if we return 0 from our can_receive
>> function then the chardev layer should decide it has
>> nothing to do until the pl011 later calls
>> qemu_chr_fe_accept_input(), I think.
>>
>> I've cc'd Paolo and Marc-André Lureau as the chardev
>> maintainers.
>
> Windows named pipes do not support the equivalent of "select",
> so it's possible that they cause a busy wait.

That's not the end that's a problem. Here we know we have
data available from the Windows end to read, we just
can't feed it to the QEMU UART model yet because the
UART model is saying "my FIFO is full, try later".
We should be able to handle that. (I couldn't figure
out how it works for the socket code either.)

thanks
-- PMM

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-22 10:28                             ` Jiahuan Zhang
@ 2017-03-22 11:27                               ` Paolo Bonzini
  2017-03-23 10:12                                 ` Jiahuan Zhang
  0 siblings, 1 reply; 26+ messages in thread
From: Paolo Bonzini @ 2017-03-22 11:27 UTC (permalink / raw)
  To: Jiahuan Zhang; +Cc: QEMU Developers



On 22/03/2017 11:28, Jiahuan Zhang wrote:
> 
>     A function that lets a process sleep until data is available on the
>     socket.  The solution is to rewrite Windows chardev handling in QEMU to
>     use threads or overlapped I/O.
> 
> Yes, socket is working well. Will you add the "select" to pipe
> implementation?

It's Windows that doesn't support it (the Windows function name is
WaitForSingleObject).

Paolo

> Or shall I look into it and fix? Since in my case, I prefer windows pipe
> to socket.
> But if I do, definitly, I will spend much more effort than you, the experts.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-22 11:07                         ` Peter Maydell
@ 2017-03-22 11:33                           ` Paolo Bonzini
  0 siblings, 0 replies; 26+ messages in thread
From: Paolo Bonzini @ 2017-03-22 11:33 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Jiahuan Zhang, QEMU Developers, Marc-André Lureau



On 22/03/2017 12:07, Peter Maydell wrote:
> That's not the end that's a problem. Here we know we have
> data available from the Windows end to read, we just
> can't feed it to the QEMU UART model yet because the
> UART model is saying "my FIFO is full, try later".
> We should be able to handle that. (I couldn't figure
> out how it works for the socket code either.)

On every iteration of the glib main loop, tcp_chr_read_poll returns zero
and io_watch_poll_prepare removes any previously created QIOChannel
event source for the file descriptor

When hw/char/pl011.c has free space in the FIFO tcp_chr_read_poll
returns nonzero, io_watch_poll_prepare adds again the QIOChannel event
source, the event source calls tcp_chr_read which reads from the socket
and passes the data to the PL011.

qemu_chr_fe_accept_input is only needed to force another call to
tcp_chr_read_poll.

Paolo

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-22 11:27                               ` Paolo Bonzini
@ 2017-03-23 10:12                                 ` Jiahuan Zhang
  2017-03-23 10:35                                   ` Paolo Bonzini
  0 siblings, 1 reply; 26+ messages in thread
From: Jiahuan Zhang @ 2017-03-23 10:12 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers, Peter Maydell

On 22 March 2017 at 12:27, Paolo Bonzini <pbonzini@redhat.com> wrote:

>
>
> On 22/03/2017 11:28, Jiahuan Zhang wrote:
> >
> >     A function that lets a process sleep until data is available on the
> >     socket.  The solution is to rewrite Windows chardev handling in QEMU
> to
> >     use threads or overlapped I/O.
> >
> > Yes, socket is working well. Will you add the "select" to pipe
> > implementation?
>
> It's Windows that doesn't support it (the Windows function name is
> WaitForSingleObject).


Hi, I have checked the Windows chardev implimentation in QEMU.
I learned from char-win-stdio.c to using thread and WaitForSingleObject for
interlocking.
char-win-stdio.c uses qemu_add_wait_object().
Char-pipe.c uses qemu_add_polling_cb().
I found all over qemu, only char-pipe uses qemu_add_polling_cb().
Does this mean that somebody has already looked into this issue,
and failed in using qemu_add_wait_object(),
and then he/she created qemu_add_polling_cb()?

If so, what I am going to do is just something has been proved to be
useless.
Please tell me if my guess is true.

Best,
Huan

>
> Paolo
>
> > Or shall I look into it and fix? Since in my case, I prefer windows pipe
> > to socket.
> > But if I do, definitly, I will spend much more effort than you, the
> experts.
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-23 10:12                                 ` Jiahuan Zhang
@ 2017-03-23 10:35                                   ` Paolo Bonzini
  2017-03-23 17:28                                     ` Jiahuan Zhang
  0 siblings, 1 reply; 26+ messages in thread
From: Paolo Bonzini @ 2017-03-23 10:35 UTC (permalink / raw)
  To: Jiahuan Zhang; +Cc: QEMU Developers, Peter Maydell



On 23/03/2017 11:12, Jiahuan Zhang wrote:
> 
>     It's Windows that doesn't support it (the Windows function name is
>     WaitForSingleObject).
> 
> 
> Hi, I have checked the Windows chardev implimentation in QEMU.
> I learned from char-win-stdio.c to using thread and WaitForSingleObject
> for interlocking.
> char-win-stdio.c uses qemu_add_wait_object().
> Char-pipe.c uses qemu_add_polling_cb().
> I found all over qemu, only char-pipe uses qemu_add_polling_cb().
> Does this mean that somebody has already looked into this issue,
> and failed in using qemu_add_wait_object(),
> and then he/she created qemu_add_polling_cb()?

I don't know, but using threads sounds like a way to solve the bug, indeed.

Thanks,

Paolo

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-23 10:35                                   ` Paolo Bonzini
@ 2017-03-23 17:28                                     ` Jiahuan Zhang
  2017-03-23 17:31                                       ` Paolo Bonzini
  0 siblings, 1 reply; 26+ messages in thread
From: Jiahuan Zhang @ 2017-03-23 17:28 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers, Peter Maydell

Hi, the method doesn't work for pipe. It still causes the same issue.
The only difference is that the first byte in the UART fifo can be read by
the guest app.
So now my guest app can immediately read 17bytes when the host is sending
data continuously,
then guest app is unable to read.

Now there is a solution-to-be. Set the qemu pipe chardev to wait for 1
millisecond before do a next ReadFile(),
then the pl011 can deliver the complete large data by the 16-byte fifo
continuously to the guest app.

Is it rational? Or is this host -CPU-dependent?

Regards,
Huan

On 23 March 2017 at 11:35, Paolo Bonzini <pbonzini@redhat.com> wrote:

>
>
> On 23/03/2017 11:12, Jiahuan Zhang wrote:
> >
> >     It's Windows that doesn't support it (the Windows function name is
> >     WaitForSingleObject).
> >
> >
> > Hi, I have checked the Windows chardev implimentation in QEMU.
> > I learned from char-win-stdio.c to using thread and WaitForSingleObject
> > for interlocking.
> > char-win-stdio.c uses qemu_add_wait_object().
> > Char-pipe.c uses qemu_add_polling_cb().
> > I found all over qemu, only char-pipe uses qemu_add_polling_cb().
> > Does this mean that somebody has already looked into this issue,
> > and failed in using qemu_add_wait_object(),
> > and then he/she created qemu_add_polling_cb()?
>
> I don't know, but using threads sounds like a way to solve the bug, indeed.
>
> Thanks,
>
> Paolo
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-23 17:28                                     ` Jiahuan Zhang
@ 2017-03-23 17:31                                       ` Paolo Bonzini
  2017-03-24  7:24                                         ` Jiahuan Zhang
  0 siblings, 1 reply; 26+ messages in thread
From: Paolo Bonzini @ 2017-03-23 17:31 UTC (permalink / raw)
  To: Jiahuan Zhang; +Cc: QEMU Developers, Peter Maydell



On 23/03/2017 18:28, Jiahuan Zhang wrote:
> Hi, the method doesn't work for pipe. It still causes the same issue.
> The only difference is that the first byte in the UART fifo can be read
> by the guest app.
> So now my guest app can immediately read 17bytes when the host is
> sending data continuously,
> then guest app is unable to read.
> 
> Now there is a solution-to-be. Set the qemu pipe chardev to wait for 1
> millisecond before do a next ReadFile(),
> then the pl011 can deliver the complete large data by the 16-byte fifo
> continuously to the guest app.
> 
> Is it rational? Or is this host -CPU-dependent?

Post the patch, maybe you have a bug.

Paolo

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-23 17:31                                       ` Paolo Bonzini
@ 2017-03-24  7:24                                         ` Jiahuan Zhang
  2017-03-24 10:00                                           ` Jiahuan Zhang
  0 siblings, 1 reply; 26+ messages in thread
From: Jiahuan Zhang @ 2017-03-24  7:24 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers, Peter Maydell

[-- Attachment #1: Type: text/plain, Size: 845 bytes --]

Hi, here are the patch files for char-pipe.c, char-win.c, char-win.h


On 23 March 2017 at 18:31, Paolo Bonzini <pbonzini@redhat.com> wrote:

>
>
> On 23/03/2017 18:28, Jiahuan Zhang wrote:
> > Hi, the method doesn't work for pipe. It still causes the same issue.
> > The only difference is that the first byte in the UART fifo can be read
> > by the guest app.
> > So now my guest app can immediately read 17bytes when the host is
> > sending data continuously,
> > then guest app is unable to read.
> >
> > Now there is a solution-to-be. Set the qemu pipe chardev to wait for 1
> > millisecond before do a next ReadFile(),
> > then the pl011 can deliver the complete large data by the 16-byte fifo
> > continuously to the guest app.
> >
> > Is it rational? Or is this host -CPU-dependent?
>
> Post the patch, maybe you have a bug.
>
> Paolo
>

[-- Attachment #2: char-pipe.patch --]
[-- Type: application/octet-stream, Size: 3247 bytes --]

--- char-pipe.c	2017-03-24 08:08:13.999237000 +0100
+++ char-pipe_new.c	2017-03-24 08:17:00.580769100 +0100
@@ -35,6 +35,67 @@
 #define MAXCONNECT 1
 #define NTIMEOUT 5000
 
+static DWORD WINAPI win_chr_pipe_thread(LPVOID param)
+{
+    //Chardev *chr = CHARDEV(param);
+    WinChardev *s = WIN_CHARDEV(param);
+    DWORD size;
+
+    int ret;
+
+    ZeroMemory(&s->orecv, sizeof(s->orecv));
+    s->orecv.hEvent = s->hrecv;
+	while (1) {
+
+		PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
+		if (size>0) {
+				// Wait for one byte
+		    Sleep(1);
+			ret = ReadFile(s->hcom, &s->win_pipe_buf, 1, &size, &s->orecv);
+			printf("			%s buf = %c size = %lu\n", __func__, s->win_pipe_buf, size);
+
+			if (!ret) {
+				break;
+			}
+			if (!size) {
+				break;
+			}
+
+			// Some terminal emulator returns \r\n for Enter, just pass \n
+			if (s->win_pipe_buf == '\r') {
+				 continue;
+			}
+
+			// Signal the main thread and wait until the byte was eaten
+			if (!SetEvent(s->hpipeInputReadyEvent)) {
+				 break;
+			}
+			printf("			%s the main thread is signaled\n", __func__);
+			if (WaitForSingleObject(s->hpipeInputDoneEvent, INFINITE) != WAIT_OBJECT_0) {
+				 break;
+			}
+			printf("			%s the byte was eaten\n", __func__);
+		}
+	}
+    qemu_del_wait_object(s->hpipeInputReadyEvent, NULL, NULL);
+    return 0;
+}
+
+static void win_pipe_thread_wait_func(void *opaque)
+{
+    Chardev *chr = CHARDEV(opaque);
+    WinChardev *s = WIN_CHARDEV(opaque);
+
+	if (qemu_chr_be_can_write(chr)) {
+		qemu_chr_be_write(chr, &s->win_pipe_buf, 1);
+		printf("			%s, s->win_pipe_buf = %x\n",__func__, s->win_pipe_buf);
+		SetEvent(s->hpipeInputDoneEvent); //force the byte is eaten by the fifo
+		printf("			%s the input thread is signaled\n", __func__);
+	}
+
+   // SetEvent(s->hpipeInputDoneEvent);
+	//printf("			%s the input thread is signaled\n", __func__);
+}
 static int win_chr_pipe_init(Chardev *chr, const char *filename,
                              Error **errp)
 {
@@ -94,8 +155,38 @@
         ov.hEvent = NULL;
     }
 
-    qemu_add_polling_cb(win_chr_pipe_poll, chr);
-    return 0;
+     // for interlocking
+    DWORD   dwId;
+
+
+    s->hpipeInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+    s->hpipeInputDoneEvent  = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if (s->hpipeInputReadyEvent == INVALID_HANDLE_VALUE
+        || s->hpipeInputDoneEvent == INVALID_HANDLE_VALUE) {
+        error_setg(errp, "cannot create event");
+        goto err2;
+    }
+
+    if (qemu_add_wait_object(s->hpipeInputReadyEvent, win_pipe_thread_wait_func, chr)) {
+        error_setg(errp, "qemu_add_wait_object: failed");
+        goto err2;
+    }
+
+    s->hpipeInputThread = CreateThread(NULL, 0, win_chr_pipe_thread, chr, 0, &dwId);
+    if (s->hpipeInputThread == INVALID_HANDLE_VALUE) {
+        error_setg(errp, "cannot create stdio thread");
+        goto err3;
+    }
+
+     return 0;
+
+err3:
+    qemu_del_wait_object(s->hpipeInputReadyEvent, NULL, NULL);
+    return -1;
+err2:
+    CloseHandle(s->hpipeInputReadyEvent);
+    CloseHandle(s->hpipeInputDoneEvent);
+    return -1;
 
  fail:
     return -1;

[-- Attachment #3: char-win.h.patch --]
[-- Type: application/octet-stream, Size: 415 bytes --]

--- char-win.h	2017-03-22 14:55:04.713163000 +0100
+++ char-win_new.h	2017-03-24 08:20:23.934769100 +0100
@@ -38,6 +38,11 @@
     OVERLAPPED osend;
     /* FIXME: file/console do not finalize */
     bool skip_free;
+	//for interlocking
+    uint8_t win_pipe_buf;
+    HANDLE  hpipeInputReadyEvent;
+    HANDLE  hpipeInputDoneEvent;
+    HANDLE  hpipeInputThread;
 } WinChardev;
 
 #define NSENDBUF 2048

[-- Attachment #4: char-win.patch --]
[-- Type: application/octet-stream, Size: 727 bytes --]

--- char-win.c	2017-03-24 08:09:28.070726500 +0100
+++ char-win_new.c	2017-03-24 08:18:53.308769100 +0100
@@ -226,10 +226,14 @@
     if (s->hcom) {
         CloseHandle(s->hcom);
     }
-    if (s->fpipe) {
-        qemu_del_polling_cb(win_chr_pipe_poll, chr);
-    } else {
-        qemu_del_polling_cb(win_chr_poll, chr);
+	if (s->hpipeInputReadyEvent != INVALID_HANDLE_VALUE) {
+        CloseHandle(s->hpipeInputReadyEvent);
+    }
+    if (s->hpipeInputDoneEvent != INVALID_HANDLE_VALUE) {
+        CloseHandle(s->hpipeInputDoneEvent);
+    }
+    if (s->hpipeInputThread != INVALID_HANDLE_VALUE) {
+        TerminateThread(s->hpipeInputThread, 0);
     }
 
     qemu_chr_be_event(chr, CHR_EVENT_CLOSED);

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-24  7:24                                         ` Jiahuan Zhang
@ 2017-03-24 10:00                                           ` Jiahuan Zhang
  2017-05-01 12:06                                             ` Jiahuan Zhang
  0 siblings, 1 reply; 26+ messages in thread
From: Jiahuan Zhang @ 2017-03-24 10:00 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers, Peter Maydell

[-- Attachment #1: Type: text/plain, Size: 1339 bytes --]

Hi, now it is working with the following char-pipe_new.c.

See the patch. Doing the "if fifo has space" polling only when there are
data on the pipe, and next reading from pipe.
The sub_thread does these three things, and the main thread only does
writing to UART fifo when the subthread signalled its handler.

It is working in my case to transfer large data. Rational? Please check.

On 24 March 2017 at 08:24, Jiahuan Zhang <jiahuanzhang90@gmail.com> wrote:

> Hi, here are the patch files for char-pipe.c, char-win.c, char-win.h
>
>
> On 23 March 2017 at 18:31, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>>
>>
>> On 23/03/2017 18:28, Jiahuan Zhang wrote:
>> > Hi, the method doesn't work for pipe. It still causes the same issue.
>> > The only difference is that the first byte in the UART fifo can be read
>> > by the guest app.
>> > So now my guest app can immediately read 17bytes when the host is
>> > sending data continuously,
>> > then guest app is unable to read.
>> >
>> > Now there is a solution-to-be. Set the qemu pipe chardev to wait for 1
>> > millisecond before do a next ReadFile(),
>> > then the pl011 can deliver the complete large data by the 16-byte fifo
>> > continuously to the guest app.
>> >
>> > Is it rational? Or is this host -CPU-dependent?
>>
>> Post the patch, maybe you have a bug.
>>
>> Paolo
>>
>
>

[-- Attachment #2: char-pipe_new.patch --]
[-- Type: application/octet-stream, Size: 2989 bytes --]

--- char-pipe.c	2017-03-24 08:08:13.999237000 +0100
+++ char-pipe_new.c	2017-03-24 10:52:21.441322100 +0100
@@ -35,6 +35,61 @@
 #define MAXCONNECT 1
 #define NTIMEOUT 5000
 
+static DWORD WINAPI win_chr_pipe_thread(LPVOID param)
+{
+    Chardev *chr = CHARDEV(param);
+    WinChardev *s = WIN_CHARDEV(param);
+    DWORD size;
+
+    int ret;
+
+    ZeroMemory(&s->orecv, sizeof(s->orecv));
+    s->orecv.hEvent = s->hrecv;
+	while (1) {
+
+		PeekNamedPipe(s->hcom, NULL, 0, NULL, &size, NULL);
+		if (size>0) {
+			// Wait for one byte
+			while(!(qemu_chr_be_can_write(chr)));
+			ret = ReadFile(s->hcom, &s->win_pipe_buf, 1, &size, &s->orecv);
+			printf("			%s buf = %c size = %lu\n", __func__, s->win_pipe_buf, size);
+
+			if (!ret) {
+				break;
+			}
+			if (!size) {
+				break;
+			}
+
+			// Some terminal emulator returns \r\n for Enter, just pass \n
+			if (s->win_pipe_buf == '\r') {
+				 continue;
+			}
+
+			// Signal the main thread and wait until the byte was eaten
+			if (!SetEvent(s->hpipeInputReadyEvent)) {
+				 break;
+			}
+			printf("			%s the main thread is signaled\n", __func__);
+			if (WaitForSingleObject(s->hpipeInputDoneEvent, INFINITE) != WAIT_OBJECT_0) {
+				 break;
+			}
+			printf("			%s the byte was eaten\n", __func__);
+		}
+	}
+    qemu_del_wait_object(s->hpipeInputReadyEvent, NULL, NULL);
+    return 0;
+}
+
+static void win_pipe_thread_wait_func(void *opaque)
+{
+    Chardev *chr = CHARDEV(opaque);
+    WinChardev *s = WIN_CHARDEV(opaque);
+
+	qemu_chr_be_write(chr, &s->win_pipe_buf, 1);
+	SetEvent(s->hpipeInputDoneEvent); //force the byte is eaten by the fifo
+	}
+}
 static int win_chr_pipe_init(Chardev *chr, const char *filename,
                              Error **errp)
 {
@@ -94,8 +149,38 @@
         ov.hEvent = NULL;
     }
 
-    qemu_add_polling_cb(win_chr_pipe_poll, chr);
-    return 0;
+     // for interlocking
+    DWORD   dwId;
+
+
+    s->hpipeInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+    s->hpipeInputDoneEvent  = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if (s->hpipeInputReadyEvent == INVALID_HANDLE_VALUE
+        || s->hpipeInputDoneEvent == INVALID_HANDLE_VALUE) {
+        error_setg(errp, "cannot create event");
+        goto err2;
+    }
+
+    if (qemu_add_wait_object(s->hpipeInputReadyEvent, win_pipe_thread_wait_func, chr)) {
+        error_setg(errp, "qemu_add_wait_object: failed");
+        goto err2;
+    }
+
+    s->hpipeInputThread = CreateThread(NULL, 0, win_chr_pipe_thread, chr, 0, &dwId);
+    if (s->hpipeInputThread == INVALID_HANDLE_VALUE) {
+        error_setg(errp, "cannot create stdio thread");
+        goto err3;
+    }
+
+     return 0;
+
+err3:
+    qemu_del_wait_object(s->hpipeInputReadyEvent, NULL, NULL);
+    return -1;
+err2:
+    CloseHandle(s->hpipeInputReadyEvent);
+    CloseHandle(s->hpipeInputDoneEvent);
+    return -1;
 
  fail:
     return -1;

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [Qemu-devel] Guest application reading from pl011 without device driver
  2017-03-24 10:00                                           ` Jiahuan Zhang
@ 2017-05-01 12:06                                             ` Jiahuan Zhang
  0 siblings, 0 replies; 26+ messages in thread
From: Jiahuan Zhang @ 2017-05-01 12:06 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: QEMU Developers, Peter Maydell

Hi, can somebody help to check this host (Windows 7) to guest (Linux
4.10) Windows named pipe data transfer?
The method I implemented has while loops that makes qemu consume 100% CPU
time.
I cannot find any optimization to eliminate the loops. So sad!

Anyone has time, please help.

On 24 March 2017 at 11:00, Jiahuan Zhang <jiahuanzhang90@gmail.com> wrote:

> Hi, now it is working with the following char-pipe_new.c.
>
> See the patch. Doing the "if fifo has space" polling only when there are
> data on the pipe, and next reading from pipe.
> The sub_thread does these three things, and the main thread only does
> writing to UART fifo when the subthread signalled its handler.
>
> It is working in my case to transfer large data. Rational? Please check.
>
> On 24 March 2017 at 08:24, Jiahuan Zhang <jiahuanzhang90@gmail.com> wrote:
>
>> Hi, here are the patch files for char-pipe.c, char-win.c, char-win.h
>>
>>
>> On 23 March 2017 at 18:31, Paolo Bonzini <pbonzini@redhat.com> wrote:
>>
>>>
>>>
>>> On 23/03/2017 18:28, Jiahuan Zhang wrote:
>>> > Hi, the method doesn't work for pipe. It still causes the same issue.
>>> > The only difference is that the first byte in the UART fifo can be read
>>> > by the guest app.
>>> > So now my guest app can immediately read 17bytes when the host is
>>> > sending data continuously,
>>> > then guest app is unable to read.
>>> >
>>> > Now there is a solution-to-be. Set the qemu pipe chardev to wait for 1
>>> > millisecond before do a next ReadFile(),
>>> > then the pl011 can deliver the complete large data by the 16-byte fifo
>>> > continuously to the guest app.
>>> >
>>> > Is it rational? Or is this host -CPU-dependent?
>>>
>>> Post the patch, maybe you have a bug.
>>>
>>> Paolo
>>>
>>
>>
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2017-05-01 12:06 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-21 16:32 [Qemu-devel] Guest application reading from pl011 without device driver Jiahuan Zhang
2017-03-21 16:39 ` Peter Maydell
2017-03-21 16:47   ` Jiahuan Zhang
2017-03-21 16:50     ` Peter Maydell
2017-03-21 16:59       ` Jiahuan Zhang
2017-03-21 17:10         ` Jiahuan Zhang
2017-03-21 17:16         ` Peter Maydell
2017-03-21 17:48           ` Jiahuan Zhang
2017-03-21 17:55             ` Peter Maydell
     [not found]               ` <CAJy91CZ4Ed-HGHLkzEc1dqQbo32d-eTE1S1ovO_ZwkDdTpkQXQ@mail.gmail.com>
     [not found]                 ` <CAJy91CaCV40FgSP55qWZeZgkQ=2+E8Cr7xdbu9pn5HLEo+6JJQ@mail.gmail.com>
2017-03-21 18:11                   ` Jiahuan Zhang
2017-03-21 18:28                     ` Peter Maydell
2017-03-21 18:33                       ` Jiahuan Zhang
2017-03-22  8:40                       ` Paolo Bonzini
2017-03-22  8:48                         ` Jiahuan Zhang
2017-03-22  9:37                           ` Paolo Bonzini
2017-03-22 10:28                             ` Jiahuan Zhang
2017-03-22 11:27                               ` Paolo Bonzini
2017-03-23 10:12                                 ` Jiahuan Zhang
2017-03-23 10:35                                   ` Paolo Bonzini
2017-03-23 17:28                                     ` Jiahuan Zhang
2017-03-23 17:31                                       ` Paolo Bonzini
2017-03-24  7:24                                         ` Jiahuan Zhang
2017-03-24 10:00                                           ` Jiahuan Zhang
2017-05-01 12:06                                             ` Jiahuan Zhang
2017-03-22 11:07                         ` Peter Maydell
2017-03-22 11:33                           ` Paolo Bonzini

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.