Paul Brook wrote: >> Paul Brook wrote: >>>> A major reason for this deadlock could likely be removed by shutting >>>> down the tap (if peered) or dropping packets in user space (in case of >>>> vlan) when a NIC is stopped or otherwise shut down. Currently most (if >>>> not all) NIC models seem to signal both "queue full" and "RX disabled" >>>> via !can_receive(). >>> No. A disabled device should return true from can_recieve, then discard >>> the packets in its receive callback. Failure to do so is a bug in the >>> device. It looks like the virtio-net device may be buggy. >> That's not a virtio-only issue. In fact, we ran into this over pcnet, >> and a quick check of other popular PCI NIC models (except for rtl8139) >> revealed the same picture: They only report can_receive if their >> receiver unit is up and ready (some also include the queue state, but >> that's an "add-on"). > > If so these are also buggy. > >> I think it's clear why: "can_receive" strongly suggests that a suspended >> receiver should make the model return false. If we want to keep this >> handler, it should be refactored to something like "queue_full". > > I don't see a need to refactor anything. You just need to fix the devices > that incorrectly return false when their RX engine is disabled.
"can_receive" is a misleading name. NIC model developers will continue to make mistakes when implementing this function. And I don't think we want such implementations all around: static int rtl8139_can_receive(VLANClientState *nc) { RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque; int avail; /* Receive (drop) packets if card is disabled. */ if (!s->clock_enabled) return 1; if (!rtl8139_receiver_enabled(s)) return 1; if (rtl8139_cp_receiver_enabled(s)) { /* ??? Flow control not implemented in c+ mode. This is a hack to work around slirp deficiencies anyway. */ return 1; } else { avail = MOD2(s->RxBufferSize + s->RxBufPtr - s->RxBufAddr, s->RxBufferSize); return (avail == 0 || avail >= 1514); } } Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux