On Thu, Feb 13, 2014 at 6:06 PM, Alexey Kardashevskiy <a...@ozlabs.ru> wrote: > On 02/14/2014 01:02 AM, Max Filippov wrote: >> On Thu, Feb 13, 2014 at 5:42 PM, Alexey Kardashevskiy <a...@ozlabs.ru> wrote: >>> On 02/13/2014 11:23 PM, Max Filippov wrote: >>>> On Thu, Feb 13, 2014 at 2:34 PM, Alexey Kardashevskiy <a...@ozlabs.ru> >>>> wrote: >>>>> On 02/13/2014 07:40 PM, Max Filippov wrote: >>>>>> Hi, >>>>>> >>>>>> On Thu, Feb 13, 2014 at 11:34 AM, Alexey Kardashevskiy <a...@ozlabs.ru> >>>>>> wrote: >>>>>>> Hi! >>>>>>> >>>>>>> I am debugging spapr-vlan and hit the following issue. >>>>>>> >>>>>>> When I run QEMU as below, the kernel's DHCP client does not continue >>>>>>> till I >>>>>>> hit any key in console. If I replace spapr-vlan with >>>>>>> e1000/rtl8139/virtio-net, everything is just fine. If I use "user" >>>>>>> network >>>>>>> - everything is fine too. So the problem is with combination of >>>>>>> spapr-vlan >>>>>>> + tap. >>>>>>> >>>>>>> The issue looks like - the guest kernel boots and then prints: >>>>>>> Sending DHCP requests .. >>>>>>> and it keeps printing dots till I press key or timeout expires. tcpdump >>>>>>> (running on the tap interface) shows one DHCP request and one DHCP >>>>>>> response. >>>>>>> >>>>>>> What normally happens is that QEMU calls os_host_main_loop_wait() which >>>>>>> calls qemu_poll_ns() and it is sitting there till eventfd signals. >>>>>>> This eventfd is registered via qemu_init_main_loop() -> >>>>>>> aio_context_new() >>>>>>> -> aio_set_event_notifier() but I cannot find where it gets passed to >>>>>>> the >>>>>>> kernel (otherwise why would we need eventfd?). When eventfd signals, >>>>>>> QEMU >>>>>>> calls qemu_iohandler_poll() which checks if TAP device has something to >>>>>>> read and eventually calls tap_send(). >>>>>>> >>>>>>> However in my bad example QEMU does not exit qemu_poll_ns() on eventfd, >>>>>>> only on stdin event. >>>>>>> >>>>>>> I can see AIO eventfd created and event_notifier_test_and_clear() is >>>>>>> called >>>>>>> on it before the kernel starts using spapr-vlan. >>>>>>> >>>>>>> So. h_send_logical_lan() is called to sent a DHCP request packet. Now I >>>>>>> expect eventfd to signal but this does not happen. Have I missed some >>>>>>> reset >>>>>>> or notification request or "bottom half" (virtio-net uses them but >>>>>>> e1000/rtl8139 do not)? >>>>>> >>>>>> Sounds pretty much like the problem I had recently with opencores >>>>>> 10/100 MAC: >>>>>> https://lists.gnu.org/archive/html/qemu-devel/2014-02/msg00073.html >>>>>> >>>>>> Does the following help?: >>>>> >>>>> Yes, it does, thanks a lot! >>>>> >>>>> While we are here and you seem to understand this stuff - >>>>> how is tap expected to work to deliver a packet from the external network >>>>> to the guest? I mean what event should be triggered in what order? My >>>>> brain >>>>> is melting :( I just cannot see how receiving a packet on "tap" in the >>>>> host >>>>> kernel can make os_host_main_loop_wait() exit in QEMU so it could call >>>>> qemu_iohandler_poll() and do the job. Thanks! >>>> >>>> I'm not very experienced in this area of QEMU, so the following may be not >>>> 100% accurate. >>>> Tap file descriptor is registered among other file descriptors in an array >>>> that os_host_main_loop_wait use to poll for events. So normally packet >>>> arrives to the host, fd becomes readable, poll function completes and >>>> registered handler (see tap_update_fd_handler) is called. The handler reads >>>> packets and calls the attached NIC's NetClientInfo::receive callback >>>> through >>>> network queuing infrastructure. But once NIC doesn't process a packet or >>>> its >>>> NetClientInfo::can_receive returns false it stops polling for new packets >>>> by updating handlers associated with its fd. So NIC needs to inform the >>>> networking core when it can receive more packets by calling >>>> qemu_flush_queued_packets, which will also complete polling and deliver >>>> already queued packets. >>> >>> >>> I am more interested in details :) >>> os_host_main_loop_wait() calls glib_pollfds_fill() which puts actual fds >>> into gpollfds GArray thing. Before the tap device started, its fd is not >>> there but after the patch you proposed, tap's fd gets to the list. >>> The actual fds are put into array by g_main_context_query() (if I read gdb >>> output correctly). So there must be some callback somewhere which tells >>> this g_main_context_query() what to poll for. I put a million breakpoints >>> to know what is called but to no avail. >> >> I see that qemu_iohandler_fill puts fds into this array. And it only puts >> those >> that have write handler or read handler and can read at the moment. > > > os_host_main_loop_wait() - when things work, it waits on the tap device > too. Without your patch, it does not wait on the tap device fd (i.e. this > fd is not put to the array of fds by glib_pollfds_fill()). Where does this > difference happen - this is my question...
It is triggered by the guest adding new descriptor to the NIC RX ring. Added qemu_flush_queued_packets completes poll that doesn't have TAP fd in the array, and (assuming there were no packets queued) the next main_loop_wait -> qemu_iohandler_fill puts the TAP fd into that array: if (ioh->fd_read && (!ioh->fd_read_poll || ioh->fd_read_poll(ioh->opaque) != 0)) { events |= G_IO_IN | G_IO_HUP | G_IO_ERR; } because now NIC's can_receive (called here through ioh->fd_read_poll) returns true. -- Thanks. -- Max