All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marc Bommert <marc@brightwise.de>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] Strange behaviour in network device initialization.
Date: Sat, 18 Mar 2017 22:15:07 +0100 (CET)	[thread overview]
Message-ID: <741795585.70221.1489871707491@communicator.strato.de> (raw)
In-Reply-To: <5909E3D6-85D8-4B21-9442-CCD312A4717B@inbox.ru>

Hello development,

I ran into some behaviour I don't understand and which may be a qemu problem but which may also be my fault, since I haven't investigated much on QOM so far.
I am currently writing a NIC sysbus device based on the structure of hw/net/smc91c111.c

qemu is invoked as:

  $ qemu-system-arm -M mymachine -m 8 -kernel kernel.elf -nographic -net nic,id=myid -netdev tap,ifname=tap0,id=myid,script=no,downscript=no -device mydevice,netdev=myid


The initialization structure is a little special here. A "legacy helper" initialization function is called from the board module mymachine.c:

   for(n = 0; n < nb_nics; n++) {
        nd = &nd_table[n];
        
        if (!nd->model || strcmp(nd->model, "mydevice") == 0) {
            mydevice_init(nd, MYDEVICE_BASE, pic[17]);
            break;
        } else {
        /* We don't know this NIC model */
        }
    }
    
The init function is provided by the device module mydevice.c:

    /* Legacy helper function.  Should go away when machine config files are implemented.  */
    void mydevice_init(NICInfo *nd, uint32_t base, qemu_irq irq)
    {
        DeviceState *dev;
        SysBusDevice *s;
    
        qemu_check_nic_model(nd, "mydevice");
        dev = qdev_create(NULL, TYPE_MYDEVICE);
        s = SYS_BUS_DEVICE(dev);
        mydevice_state *state = MY_DEVICE(dev);
        
        qdev_set_nic_properties(dev, nd);
        qdev_init_nofail(dev);
        sysbus_mmio_map(s, 0, base);
        sysbus_connect_irq(s, 0, irq);
    }
    
and the actual class/instance initializers are:

    static int mydevice_init1(Object *obj)
    {
        DeviceState *dev = DEVICE(obj);
        mydevice_state *s = MY_DEVICE(dev);
        SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
        
        memory_region_init_io(&s->mmio, OBJECT(s), &mydevice_mem_ops, s,
                            "mydevice-mmio", 0x40000);
        sysbus_init_mmio(sbd, &s->mmio);
        sysbus_init_irq(sbd, &s->irq);
        
        qemu_macaddr_default_if_unset(&s->conf.macaddr);
        s->nic = qemu_new_nic(&net_mydevice_info, &s->conf,
                            object_get_typename(OBJECT(dev)), dev->id, s);
        qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
        mydevice_reset(s);
        return 0;
    }

    static void mydevice_class_init(ObjectClass *klass, void *data)
    {
        DeviceClass *dc = DEVICE_CLASS(klass);
        SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

        k->init = mydevice_init1;
        dc->reset = mydevice_reset;
        dc->vmsd = &vmstate_mydevice;
        dc->props = mydevice_properties;
    }

    static const TypeInfo mydevice_info = {
        .name          = TYPE_MYDEVICE,
        .parent        = TYPE_SYS_BUS_DEVICE,
        .instance_size = sizeof(mydevice_state),
        .class_init    = mydevice_class_init,
    };
    
    
Now, the actual problem is that mydevice_init1() is called twice and the device state is also instantiated twice. Thus, s->irq is initialized twice, but only the first one gets connected. During runtime, the second state instance is passed with a NULL s->irq in the device state to the memops. The IRQ never fires.

Here are the stack traces of the both initialization calls:

#0  mydevice_init1 (obj=0x5555573bb010) at /home/brightwise/qemu-2.8.0/hw/mymachine/mydevice.c:700
#1  0x0000555555a020f5 in sysbus_device_init (dev=0x5555573bb010) at hw/core/sysbus.c:211
#2  0x00005555559fae58 in device_realize (dev=0x5555573bb010, errp=0x7fffffffdbd0) at hw/core/qdev.c:213
#3  0x00005555559fc96f in device_set_realized (obj=0x5555573bb010, value=true, errp=0x7fffffffdd70) at hw/core/qdev.c:918
#4  0x0000555555bd733c in property_set_bool (obj=0x5555573bb010, v=0x5555573bdb20, name=0x5555560bd162 "realized", opaque=0x55555738eca0, errp=0x7fffffffdd70) at qom/object.c:1854
#5  0x0000555555bd5847 in object_property_set (obj=0x5555573bb010, v=0x5555573bdb20, name=0x5555560bd162 "realized", errp=0x7fffffffdd70) at qom/object.c:1088
#6  0x0000555555bd866f in object_property_set_qobject (obj=0x5555573bb010, value=0x5555573bda90, name=0x5555560bd162 "realized", errp=0x7fffffffdd70) at qom/qom-qobject.c:27
#7  0x0000555555bd5aea in object_property_set_bool (obj=0x5555573bbst ask on the mailing list for someone else to do it on your behalf (self-creation is prohibited to cut down on spam accounts).
Start with reading the QEMU wiki.
Contribute to the QEMU wiki by adding new topics or im010, value=true, name=0x5555560bd162 "realized", errp=0x7fffffffdd70) at qom/object.c:1157
#8  0x00005555559fb423 in qdev_init_nofail (dev=0x5555573bb010) at hw/core/qdev.c:358
#9  0x000055555585705e in mydevice_init (nd=0x555556b40280 <nd_table>, base=1310720, irq=0x555557334550) at /home/brightwise/qemu-2.8.0/hw/mymachine/mydevice.c:776
#10 0x000055555585459a in mymachine_init (machine=0x555557038dc0, board_id=256) at /home/brightwise/qemu-2.8.0/hw/mymachine/mymachine.c:341
#11 0x00005555558546ad in _machine_init (machine=0x555557038dc0) at /home/brightwise/qemu-2.8.0/hw/mymachine/mymachine.c:377
#12 0x000055555596ec3d in main (argc=14, argv=0x7fffffffe358, envp=0x7fffffffe3d0) at vl.c:4548

and 

#0  mydevice_init1 (obj=0x5555573eaea0) at /home/brightwise/qemu-2.8.0/hw/mymachine/mydevice.c:700
#1  0x0000555555a020f5 in sysbus_device_init (dev=0x5555573eaea0) at hw/core/sysbus.c:211
#2  0x00005555559fae58 in device_realize (dev=0x5555573eaea0, errp=0x7fffffffdcf0) at hw/core/qdev.c:213
#3  0x00005555559fc96f in device_set_realized (obj=0x5555573eaea0, value=true, errp=0x7fffffffdea0) at hw/core/qdev.c:918
#4  0x0000555555bd733c in property_set_bool (obj=0x5555573eaea0, v=0x5555573eda40, name=0x55555607cce6 "realized", opaque=0x5555573bef50, errp=0x7fffffffdea0) at qom/object.c:1854
#5  0x0000555555bd5847 in object_property_set (obj=0x5555573eaea0, v=0x5555573eda40, name=0x55555607cce6 "realized", errp=0x7fffffffdea0) at qom/object.c:1088
#6  0x0000555555bd866f in object_property_set_qobject (obj=0x5555573eaea0, value=0x5555573ed930, name=0x55555607cce6 "realized", errp=0x7fffffffdea0) at qom/qom-qobject.c:27
#7  0x0000555555bd5aea in object_property_set_bool (obj=0x5555573eaea0, value=true, name=0x55555607cce6 "realized", errp=0x7fffffffdea0) at qom/object.c:1157
#8  0x0000555555957364 in qdev_device_add (opts=0x555556fdbc90, errp=0x7fffffffdf18) at qdev-monitor.c:623
#9  0x0000555555969a13 in device_init_func (opaque=0x0, opts=0x555556fdbc90, errp=0x0) at vl.c:2373
#10 0x0000555555cc801b in qemu_opts_foreach (list=0x55555659e120 <qemu_device_opts>, func=0x5555559699d5 <device_init_func>, opaque=0x0, errp=0x0) at util/qemu-option.c:1116
#11 0x000055555596ecf0 in main (argc=14, argv=0x7fffffffe358, envp=0x7fffffffe3d0) at vl.c:4574


Any help on this is greatly appreciated. Questions are:

- Is this a specific problem of the network device smc91c111.c (and maybe others, too) in the first place and I've cloned that issue when copying the structure of that device module? I haven't tested smc91c111.c. Should I? I guess this stuff is widely used and should work?

- If not, what is the problem here? I would guess it is related to the "realized" property which is not set with the first initialization and eventually, the device is initialized a second time.

Sorry, if this turn out the be a noobish question. I've got it running in a hacked version, but I wanted to figure out what the exact problem is. Any ideas?

TIA
Marc

  reply	other threads:[~2017-03-18 21:15 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-18 18:15 [Qemu-devel] Error checking and qemu_thread_create Anton Volkov
2017-03-18 21:15 ` Marc Bommert [this message]
2017-03-18 22:22   ` [Qemu-devel] Strange behaviour in network device initialization Peter Maydell
2017-03-19 13:41     ` Marc Bommert

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=741795585.70221.1489871707491@communicator.strato.de \
    --to=marc@brightwise.de \
    --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 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.