All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH for-4.0 0/6] qemu/queue.h usage cleanup, improved QTAILQ API
@ 2018-12-06 23:23 Paolo Bonzini
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 1/6] qemu/queue.h: do not access tqe_prev directly Paolo Bonzini
                   ` (5 more replies)
  0 siblings, 6 replies; 16+ messages in thread
From: Paolo Bonzini @ 2018-12-06 23:23 UTC (permalink / raw)
  To: qemu-devel

This series includes two changes that are a bit intertwined.

The main one is to reimplement QTAILQ in a way that simplifies
backwards walking of the list.  The in-memory layout actually
stays the same, but the C description of it changes so that
(also thanks to typeof) you don't have to specify a name for
the "head" struct in QTAILQ_{LAST,PREV,FOREACH_REVERSE}.
This is done in patches 1, 4 and 5.

Once you do this, you actually almost never need to define
a named head struct.  Therefore, the series also cleans up
other cases where the struct was given a name unnecessarily,
and ensures that those queue.h structs are given a typedef
and a camel case name, similar to all other structs in QEMU.
This is done in patches 2 and 3, and at the end of the series
we can add a checkpatch test for it in patch 6.

Paolo Bonzini (6):
  qemu/queue.h: do not access tqe_prev directly
  qemu/queue.h: leave head structs anonymous unless necessary
  qemu/queue.h: typedef QTAILQ heads
  qemu/queue.h: reimplement QTAILQ without pointer-to-pointers
  qemu/queue.h: simplify reverse access to QTAILQ
  checkpatch: warn about queue/queue.h head structs that are not
    typedef-ed

 accel/kvm/kvm-all.c                     |   4 +-
 block/gluster.c                         |   2 +-
 block/mirror.c                          |   2 +-
 block/qcow2-bitmap.c                    |   4 +-
 block/qcow2.h                           |   2 +-
 block/sheepdog.c                        |   6 +-
 block/vhdx.h                            |   2 +-
 blockdev.c                              |   4 +-
 contrib/ivshmem-client/ivshmem-client.h |   4 +-
 contrib/ivshmem-server/ivshmem-server.h |   5 +-
 cpus-common.c                           |   2 +-
 dump.c                                  |   2 +-
 exec.c                                  |   5 +-
 fsdev/qemu-fsdev.c                      |   2 +-
 hw/block/nvme.h                         |   8 +-
 hw/block/xen_disk.c                     |   6 +-
 hw/core/qdev.c                          |   4 +-
 hw/core/reset.c                         |   2 +-
 hw/i386/xen/xen-mapcache.c              |   2 +-
 hw/ppc/spapr_iommu.c                    |   2 +-
 hw/scsi/scsi-bus.c                      |   2 +-
 hw/usb/ccid-card-emulated.c             |   4 +-
 hw/usb/combined-packet.c                |   2 +-
 hw/usb/dev-mtp.c                        |   4 +-
 hw/usb/dev-network.c                    |   2 +-
 hw/usb/hcd-ehci.c                       |   2 +-
 hw/usb/hcd-ehci.h                       |   2 +-
 hw/usb/hcd-uhci.c                       |   4 +-
 hw/usb/xen-usb.c                        |   6 +-
 hw/vfio/common.c                        |   4 +-
 hw/watchdog/watchdog.c                  |   2 +-
 hw/xen/xen_pvdev.c                      |   4 +-
 include/exec/memory.h                   |   6 +-
 include/hw/qdev-core.h                  |   2 +-
 include/hw/usb.h                        |   2 +-
 include/hw/vfio/vfio-common.h           |   4 +-
 include/hw/vfio/vfio-platform.h         |   2 +-
 include/net/net.h                       |   2 +-
 include/qemu/option_int.h               |   2 +-
 include/qemu/queue.h                    | 151 +++++++++++-------------
 include/qemu/rcu_queue.h                |  45 +++----
 include/qom/cpu.h                       |   9 +-
 include/sysemu/kvm.h                    |   2 -
 include/sysemu/memory_mapping.h         |   2 +-
 include/sysemu/rng.h                    |   2 +-
 linux-user/elfload.c                    |   2 +-
 memory.c                                |  19 ++-
 memory_mapping.c                        |   2 +-
 migration/block-dirty-bitmap.c          |   2 +-
 migration/block.c                       |   4 +-
 migration/ram.c                         |   2 +-
 monitor.c                               |   4 +-
 net/filter.c                            |   2 +-
 net/net.c                               |   2 +-
 net/queue.c                             |   2 +-
 net/slirp.c                             |   2 +-
 qga/commands-posix.c                    |   2 +-
 scripts/checkpatch.pl                   |   5 +
 scripts/cocci-macro-file.h              |  24 ++--
 slirp/slirp.c                           |   2 +-
 target/arm/kvm.c                        |   2 +-
 target/i386/hax-mem.c                   |   2 +-
 tcg/tcg.c                               |   2 +-
 tcg/tcg.h                               |   6 +-
 tests/libqos/malloc.c                   |   2 +-
 tests/test-rcu-list.c                   |   2 +-
 tests/test-vmstate.c                    |   8 +-
 ui/console.c                            |   4 +-
 ui/input.c                              |  14 ++-
 util/qemu-option.c                      |   4 +-
 vl.c                                    |   2 +-
 71 files changed, 216 insertions(+), 247 deletions(-)

-- 
2.19.2

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

* [Qemu-devel] [PATCH 1/6] qemu/queue.h: do not access tqe_prev directly
  2018-12-06 23:23 [Qemu-devel] [PATCH for-4.0 0/6] qemu/queue.h usage cleanup, improved QTAILQ API Paolo Bonzini
@ 2018-12-06 23:23 ` Paolo Bonzini
  2018-12-07  7:14   ` Markus Armbruster
  2018-12-07 10:14   ` Philippe Mathieu-Daudé
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 2/6] qemu/queue.h: leave head structs anonymous unless necessary Paolo Bonzini
                   ` (4 subsequent siblings)
  5 siblings, 2 replies; 16+ messages in thread
From: Paolo Bonzini @ 2018-12-06 23:23 UTC (permalink / raw)
  To: qemu-devel

Use the QTAILQ_IN_USE macro instead, it does the same thing but the next
patch will change it to a different definition.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 blockdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/blockdev.c b/blockdev.c
index 81f95d920b..7604b2183b 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -4259,7 +4259,7 @@ void qmp_blockdev_del(const char *node_name, Error **errp)
         goto out;
     }
 
-    if (!bs->monitor_list.tqe_prev) {
+    if (!QTAILQ_IN_USE(bs, monitor_list)) {
         error_setg(errp, "Node %s is not owned by the monitor",
                    bs->node_name);
         goto out;
-- 
2.19.2

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

* [Qemu-devel] [PATCH 2/6] qemu/queue.h: leave head structs anonymous unless necessary
  2018-12-06 23:23 [Qemu-devel] [PATCH for-4.0 0/6] qemu/queue.h usage cleanup, improved QTAILQ API Paolo Bonzini
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 1/6] qemu/queue.h: do not access tqe_prev directly Paolo Bonzini
@ 2018-12-06 23:23 ` Paolo Bonzini
  2018-12-07  7:28   ` Markus Armbruster
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 3/6] qemu/queue.h: typedef QTAILQ heads Paolo Bonzini
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: Paolo Bonzini @ 2018-12-06 23:23 UTC (permalink / raw)
  To: qemu-devel

Most list head structs need not be given a name.  In most cases the
name is given just in case one is going to use QTAILQ_LAST, QTAILQ_PREV
or reverse iteration, but this does not apply to lists of other kinds,
and even for QTAILQ in practice this is only rarely needed.  In addition,
we will soon reimplement those macros completely so that they do not
need a name for the head struct.  So clean up everything, not giving a
name except in the rare case where it is necessary.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 accel/kvm/kvm-all.c                     | 4 ++--
 block/gluster.c                         | 2 +-
 block/mirror.c                          | 2 +-
 block/qcow2-bitmap.c                    | 4 +---
 block/qcow2.h                           | 2 +-
 block/sheepdog.c                        | 6 +++---
 block/vhdx.h                            | 2 +-
 blockdev.c                              | 2 +-
 contrib/ivshmem-client/ivshmem-client.h | 4 +---
 contrib/ivshmem-server/ivshmem-server.h | 5 +----
 exec.c                                  | 2 +-
 fsdev/qemu-fsdev.c                      | 2 +-
 hw/block/nvme.h                         | 8 ++++----
 hw/block/xen_disk.c                     | 6 +++---
 hw/core/reset.c                         | 2 +-
 hw/i386/xen/xen-mapcache.c              | 2 +-
 hw/ppc/spapr_iommu.c                    | 2 +-
 hw/usb/ccid-card-emulated.c             | 4 ++--
 hw/usb/dev-network.c                    | 2 +-
 hw/usb/xen-usb.c                        | 6 +++---
 hw/vfio/common.c                        | 4 ++--
 hw/watchdog/watchdog.c                  | 2 +-
 hw/xen/xen_pvdev.c                      | 4 ++--
 include/exec/memory.h                   | 4 ++--
 include/hw/vfio/vfio-common.h           | 4 ++--
 include/hw/vfio/vfio-platform.h         | 2 +-
 include/qom/cpu.h                       | 4 ++--
 include/sysemu/kvm.h                    | 2 --
 include/sysemu/rng.h                    | 2 +-
 linux-user/elfload.c                    | 2 +-
 memory.c                                | 2 +-
 migration/block-dirty-bitmap.c          | 2 +-
 migration/block.c                       | 4 ++--
 migration/ram.c                         | 2 +-
 monitor.c                               | 4 ++--
 net/queue.c                             | 2 +-
 net/slirp.c                             | 2 +-
 slirp/slirp.c                           | 2 +-
 target/arm/kvm.c                        | 2 +-
 target/i386/hax-mem.c                   | 2 +-
 tcg/tcg.h                               | 2 +-
 tests/test-rcu-list.c                   | 2 +-
 vl.c                                    | 2 +-
 43 files changed, 60 insertions(+), 69 deletions(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 4880a05399..4e1de942ce 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -86,7 +86,7 @@ struct KVMState
     int robust_singlestep;
     int debugregs;
 #ifdef KVM_CAP_SET_GUEST_DEBUG
-    struct kvm_sw_breakpoint_head kvm_sw_breakpoints;
+    QTAILQ_HEAD(, kvm_sw_breakpoint) kvm_sw_breakpoints;
 #endif
     int many_ioeventfds;
     int intx_set_mask;
@@ -102,7 +102,7 @@ struct KVMState
     int nr_allocated_irq_routes;
     unsigned long *used_gsi_bitmap;
     unsigned int gsi_count;
-    QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE];
+    QTAILQ_HEAD(, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE];
 #endif
     KVMMemoryListener memory_listener;
     QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus;
diff --git a/block/gluster.c b/block/gluster.c
index 5e300c96c8..72891060e3 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -72,7 +72,7 @@ typedef struct ListElement {
     GlfsPreopened saved;
 } ListElement;
 
-static QLIST_HEAD(glfs_list, ListElement) glfs_list;
+static QLIST_HEAD(, ListElement) glfs_list;
 
 static QemuOptsList qemu_gluster_create_opts = {
     .name = "qemu-gluster-create-opts",
diff --git a/block/mirror.c b/block/mirror.c
index 8f52c6215d..6250cc3c87 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -72,7 +72,7 @@ typedef struct MirrorBlockJob {
     unsigned long *in_flight_bitmap;
     int in_flight;
     int64_t bytes_in_flight;
-    QTAILQ_HEAD(MirrorOpList, MirrorOp) ops_in_flight;
+    QTAILQ_HEAD(, MirrorOp) ops_in_flight;
     int ret;
     bool unmap;
     int target_cluster_size;
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index accebef4cf..b946301429 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -77,8 +77,6 @@ typedef struct Qcow2BitmapTable {
     uint32_t size; /* number of 64bit entries */
     QSIMPLEQ_ENTRY(Qcow2BitmapTable) entry;
 } Qcow2BitmapTable;
-typedef QSIMPLEQ_HEAD(Qcow2BitmapTableList, Qcow2BitmapTable)
-    Qcow2BitmapTableList;
 
 typedef struct Qcow2Bitmap {
     Qcow2BitmapTable table;
@@ -1316,7 +1314,7 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp)
     int ret;
     Qcow2BitmapList *bm_list;
     Qcow2Bitmap *bm;
-    Qcow2BitmapTableList drop_tables;
+    QSIMPLEQ_HEAD(, Qcow2BitmapTable) drop_tables;
     Qcow2BitmapTable *tb, *tb_next;
 
     if (!bdrv_has_changed_persistent_bitmaps(bs)) {
diff --git a/block/qcow2.h b/block/qcow2.h
index 8662b68575..d747dd14a2 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -281,7 +281,7 @@ typedef struct BDRVQcow2State {
     uint8_t *cluster_cache;
     uint8_t *cluster_data;
     uint64_t cluster_cache_offset;
-    QLIST_HEAD(QCowClusterAlloc, QCowL2Meta) cluster_allocs;
+    QLIST_HEAD(, QCowL2Meta) cluster_allocs;
 
     uint64_t *refcount_table;
     uint64_t refcount_table_offset;
diff --git a/block/sheepdog.c b/block/sheepdog.c
index 0125df9d49..90ab43baa4 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -391,12 +391,12 @@ struct BDRVSheepdogState {
     uint32_t aioreq_seq_num;
 
     /* Every aio request must be linked to either of these queues. */
-    QLIST_HEAD(inflight_aio_head, AIOReq) inflight_aio_head;
-    QLIST_HEAD(failed_aio_head, AIOReq) failed_aio_head;
+    QLIST_HEAD(, AIOReq) inflight_aio_head;
+    QLIST_HEAD(, AIOReq) failed_aio_head;
 
     CoMutex queue_lock;
     CoQueue overlapping_queue;
-    QLIST_HEAD(inflight_aiocb_head, SheepdogAIOCB) inflight_aiocb_head;
+    QLIST_HEAD(, SheepdogAIOCB) inflight_aiocb_head;
 };
 
 typedef struct BDRVSheepdogReopenState {
diff --git a/block/vhdx.h b/block/vhdx.h
index 3a5f5293ad..1bfb4e4f73 100644
--- a/block/vhdx.h
+++ b/block/vhdx.h
@@ -398,7 +398,7 @@ typedef struct BDRVVHDXState {
 
     bool log_replayed_on_open;
 
-    QLIST_HEAD(VHDXRegionHead, VHDXRegionEntry) regions;
+    QLIST_HEAD(, VHDXRegionEntry) regions;
 } BDRVVHDXState;
 
 void vhdx_guid_generate(MSGUID *guid);
diff --git a/blockdev.c b/blockdev.c
index 7604b2183b..60d05ec7f5 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2269,7 +2269,7 @@ void qmp_transaction(TransactionActionList *dev_list,
     BlkActionState *state, *next;
     Error *local_err = NULL;
 
-    QSIMPLEQ_HEAD(snap_bdrv_states, BlkActionState) snap_bdrv_states;
+    QSIMPLEQ_HEAD(, BlkActionState) snap_bdrv_states;
     QSIMPLEQ_INIT(&snap_bdrv_states);
 
     /* Does this transaction get canceled as a group on failure?
diff --git a/contrib/ivshmem-client/ivshmem-client.h b/contrib/ivshmem-client/ivshmem-client.h
index 5ee942262b..fe3cc4a03d 100644
--- a/contrib/ivshmem-client/ivshmem-client.h
+++ b/contrib/ivshmem-client/ivshmem-client.h
@@ -46,9 +46,7 @@ typedef struct IvshmemClientPeer {
     int vectors[IVSHMEM_CLIENT_MAX_VECTORS]; /**< one fd per vector */
     unsigned vectors_count;                  /**< number of vectors */
 } IvshmemClientPeer;
-QTAILQ_HEAD(IvshmemClientPeerList, IvshmemClientPeer);
 
-typedef struct IvshmemClientPeerList IvshmemClientPeerList;
 typedef struct IvshmemClient IvshmemClient;
 
 /**
@@ -73,7 +71,7 @@ struct IvshmemClient {
     int sock_fd;                        /**< unix sock filedesc */
     int shm_fd;                         /**< shm file descriptor */
 
-    IvshmemClientPeerList peer_list;    /**< list of peers */
+    QTAILQ_HEAD(, IvshmemClientPeer) peer_list;    /**< list of peers */
     IvshmemClientPeer local;            /**< our own infos */
 
     IvshmemClientNotifCb notif_cb;      /**< notification callback */
diff --git a/contrib/ivshmem-server/ivshmem-server.h b/contrib/ivshmem-server/ivshmem-server.h
index 4af08e1bb7..d870adb6a0 100644
--- a/contrib/ivshmem-server/ivshmem-server.h
+++ b/contrib/ivshmem-server/ivshmem-server.h
@@ -52,9 +52,6 @@ typedef struct IvshmemServerPeer {
     EventNotifier vectors[IVSHMEM_SERVER_MAX_VECTORS]; /**< one per vector */
     unsigned vectors_count;                  /**< number of vectors */
 } IvshmemServerPeer;
-QTAILQ_HEAD(IvshmemServerPeerList, IvshmemServerPeer);
-
-typedef struct IvshmemServerPeerList IvshmemServerPeerList;
 
 /**
  * Structure describing an ivshmem server
@@ -72,7 +69,7 @@ typedef struct IvshmemServer {
     unsigned n_vectors;              /**< number of vectors */
     uint16_t cur_id;                 /**< id to be given to next client */
     bool verbose;                    /**< true in verbose mode */
-    IvshmemServerPeerList peer_list; /**< list of peers */
+    QTAILQ_HEAD(, IvshmemServerPeer) peer_list; /**< list of peers */
 } IvshmemServer;
 
 /**
diff --git a/exec.c b/exec.c
index bb6170dbff..b6b2007f27 100644
--- a/exec.c
+++ b/exec.c
@@ -3464,7 +3464,7 @@ typedef struct MapClient {
 } MapClient;
 
 QemuMutex map_client_list_lock;
-static QLIST_HEAD(map_client_list, MapClient) map_client_list
+static QLIST_HEAD(, MapClient) map_client_list
     = QLIST_HEAD_INITIALIZER(map_client_list);
 
 static void cpu_unregister_map_client_do(MapClient *client)
diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c
index 7a3b87cc9e..82edf43a0d 100644
--- a/fsdev/qemu-fsdev.c
+++ b/fsdev/qemu-fsdev.c
@@ -18,7 +18,7 @@
 #include "qemu/error-report.h"
 #include "qemu/option.h"
 
-static QTAILQ_HEAD(FsDriverEntry_head, FsDriverListEntry) fsdriver_entries =
+static QTAILQ_HEAD(, FsDriverListEntry) fsdriver_entries =
     QTAILQ_HEAD_INITIALIZER(fsdriver_entries);
 
 static FsDriverTable FsDrivers[] = {
diff --git a/hw/block/nvme.h b/hw/block/nvme.h
index cabcf20c32..56c9d4b4b1 100644
--- a/hw/block/nvme.h
+++ b/hw/block/nvme.h
@@ -29,8 +29,8 @@ typedef struct NvmeSQueue {
     uint64_t    dma_addr;
     QEMUTimer   *timer;
     NvmeRequest *io_req;
-    QTAILQ_HEAD(sq_req_list, NvmeRequest) req_list;
-    QTAILQ_HEAD(out_req_list, NvmeRequest) out_req_list;
+    QTAILQ_HEAD(, NvmeRequest) req_list;
+    QTAILQ_HEAD(, NvmeRequest) out_req_list;
     QTAILQ_ENTRY(NvmeSQueue) entry;
 } NvmeSQueue;
 
@@ -45,8 +45,8 @@ typedef struct NvmeCQueue {
     uint32_t    size;
     uint64_t    dma_addr;
     QEMUTimer   *timer;
-    QTAILQ_HEAD(sq_list, NvmeSQueue) sq_list;
-    QTAILQ_HEAD(cq_req_list, NvmeRequest) req_list;
+    QTAILQ_HEAD(, NvmeSQueue) sq_list;
+    QTAILQ_HEAD(, NvmeRequest) req_list;
 } NvmeCQueue;
 
 typedef struct NvmeNamespace {
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 36eff94f84..2a254b99d0 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -82,9 +82,9 @@ struct XenBlkDev {
     int                 more_work;
 
     /* request lists */
-    QLIST_HEAD(inflight_head, ioreq) inflight;
-    QLIST_HEAD(finished_head, ioreq) finished;
-    QLIST_HEAD(freelist_head, ioreq) freelist;
+    QLIST_HEAD(, ioreq) inflight;
+    QLIST_HEAD(, ioreq) finished;
+    QLIST_HEAD(, ioreq) freelist;
     int                 requests_total;
     int                 requests_inflight;
     int                 requests_finished;
diff --git a/hw/core/reset.c b/hw/core/reset.c
index 84c8869371..9c477f2bf5 100644
--- a/hw/core/reset.c
+++ b/hw/core/reset.c
@@ -35,7 +35,7 @@ typedef struct QEMUResetEntry {
     void *opaque;
 } QEMUResetEntry;
 
-static QTAILQ_HEAD(reset_handlers, QEMUResetEntry) reset_handlers =
+static QTAILQ_HEAD(, QEMUResetEntry) reset_handlers =
     QTAILQ_HEAD_INITIALIZER(reset_handlers);
 
 void qemu_register_reset(QEMUResetHandler *func, void *opaque)
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index 4e4f069a24..02e823c5a2 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -71,7 +71,7 @@ typedef struct MapCacheRev {
 typedef struct MapCache {
     MapCacheEntry *entry;
     unsigned long nr_buckets;
-    QTAILQ_HEAD(map_cache_head, MapCacheRev) locked_entries;
+    QTAILQ_HEAD(, MapCacheRev) locked_entries;
 
     /* For most cases (>99.9%), the page address is the same. */
     MapCacheEntry *last_entry;
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 1b0880ac9e..68dacf6356 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -42,7 +42,7 @@ enum sPAPRTCEAccess {
 #define IOMMU_PAGE_SIZE(shift)      (1ULL << (shift))
 #define IOMMU_PAGE_MASK(shift)      (~(IOMMU_PAGE_SIZE(shift) - 1))
 
-static QLIST_HEAD(spapr_tce_tables, sPAPRTCETable) spapr_tce_tables;
+static QLIST_HEAD(, sPAPRTCETable) spapr_tce_tables;
 
 sPAPRTCETable *spapr_tce_find_by_liobn(target_ulong liobn)
 {
diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c
index 25976ed84f..de880a8c30 100644
--- a/hw/usb/ccid-card-emulated.c
+++ b/hw/usb/ccid-card-emulated.c
@@ -119,11 +119,11 @@ struct EmulatedState {
     char    *db;
     uint8_t  atr[MAX_ATR_SIZE];
     uint8_t  atr_length;
-    QSIMPLEQ_HEAD(event_list, EmulEvent) event_list;
+    QSIMPLEQ_HEAD(, EmulEvent) event_list;
     QemuMutex event_list_mutex;
     QemuThread event_thread_id;
     VReader *reader;
-    QSIMPLEQ_HEAD(guest_apdu_list, EmulEvent) guest_apdu_list;
+    QSIMPLEQ_HEAD(, EmulEvent) guest_apdu_list;
     QemuMutex vreader_mutex; /* and guest_apdu_list mutex */
     QemuMutex handle_apdu_mutex;
     QemuCond handle_apdu_cond;
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 385e090336..ffab3fabee 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -648,7 +648,7 @@ typedef struct USBNetState {
     char usbstring_mac[13];
     NICState *nic;
     NICConf conf;
-    QTAILQ_HEAD(rndis_resp_head, rndis_response) rndis_resp;
+    QTAILQ_HEAD(, rndis_response) rndis_resp;
 } USBNetState;
 
 #define TYPE_USB_NET "usb-net"
diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c
index 5b2e21ed18..5564eb977c 100644
--- a/hw/usb/xen-usb.c
+++ b/hw/usb/xen-usb.c
@@ -72,7 +72,7 @@ struct usbback_stub {
     USBPort       port;
     unsigned int  speed;
     bool          attached;
-    QTAILQ_HEAD(submit_q_head, usbback_req) submit_q;
+    QTAILQ_HEAD(, usbback_req) submit_q;
 };
 
 struct usbback_req {
@@ -108,8 +108,8 @@ struct usbback_info {
     int                      num_ports;
     int                      usb_ver;
     bool                     ring_error;
-    QTAILQ_HEAD(req_free_q_head, usbback_req) req_free_q;
-    QSIMPLEQ_HEAD(hotplug_q_head, usbback_hotplug) hotplug_q;
+    QTAILQ_HEAD(, usbback_req) req_free_q;
+    QSIMPLEQ_HEAD(, usbback_hotplug) hotplug_q;
     struct usbback_stub      ports[USBBACK_MAXPORTS];
     struct usbback_stub      *addr_table[USB_DEV_ADDR_SIZE];
     QEMUBH                   *bh;
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 7c185e5a2e..4262b80c44 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -37,9 +37,9 @@
 #include "trace.h"
 #include "qapi/error.h"
 
-struct vfio_group_head vfio_group_list =
+VFIOGroupList vfio_group_list =
     QLIST_HEAD_INITIALIZER(vfio_group_list);
-struct vfio_as_head vfio_address_spaces =
+static QLIST_HEAD(, VFIOAddressSpace) vfio_address_spaces =
     QLIST_HEAD_INITIALIZER(vfio_address_spaces);
 
 #ifdef CONFIG_KVM
diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c
index 33e6c20184..dce7c1db14 100644
--- a/hw/watchdog/watchdog.c
+++ b/hw/watchdog/watchdog.c
@@ -32,7 +32,7 @@
 #include "qemu/help_option.h"
 
 static WatchdogAction watchdog_action = WATCHDOG_ACTION_RESET;
-static QLIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list;
+static QLIST_HEAD(, WatchdogTimerModel) watchdog_list;
 
 void watchdog_add_model(WatchdogTimerModel *model)
 {
diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c
index aed783e844..f026556f62 100644
--- a/hw/xen/xen_pvdev.c
+++ b/hw/xen/xen_pvdev.c
@@ -31,10 +31,10 @@ struct xs_dirs {
     QTAILQ_ENTRY(xs_dirs) list;
 };
 
-static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup =
+static QTAILQ_HEAD(, xs_dirs) xs_cleanup =
     QTAILQ_HEAD_INITIALIZER(xs_cleanup);
 
-static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs =
+static QTAILQ_HEAD(, XenDevice) xendevs =
     QTAILQ_HEAD_INITIALIZER(xendevs);
 
 /* ------------------------------------------------------------- */
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 8e61450de3..ce930689cf 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -379,9 +379,9 @@ struct MemoryRegion {
     MemoryRegion *alias;
     hwaddr alias_offset;
     int32_t priority;
-    QTAILQ_HEAD(subregions, MemoryRegion) subregions;
+    QTAILQ_HEAD(, MemoryRegion) subregions;
     QTAILQ_ENTRY(MemoryRegion) subregions_link;
-    QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
+    QTAILQ_HEAD(, CoalescedMemoryRange) coalesced;
     const char *name;
     unsigned ioeventfd_nb;
     MemoryRegionIoeventfd *ioeventfds;
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 1b434d02f6..7624c9f511 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -180,8 +180,8 @@ int vfio_get_device(VFIOGroup *group, const char *name,
                     VFIODevice *vbasedev, Error **errp);
 
 extern const MemoryRegionOps vfio_region_ops;
-extern QLIST_HEAD(vfio_group_head, VFIOGroup) vfio_group_list;
-extern QLIST_HEAD(vfio_as_head, VFIOAddressSpace) vfio_address_spaces;
+typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList;
+extern VFIOGroupList vfio_group_list;
 
 #ifdef CONFIG_LINUX
 int vfio_get_region_info(VFIODevice *vbasedev, int index,
diff --git a/include/hw/vfio/vfio-platform.h b/include/hw/vfio/vfio-platform.h
index 0ee10b1d71..30d3c28d3b 100644
--- a/include/hw/vfio/vfio-platform.h
+++ b/include/hw/vfio/vfio-platform.h
@@ -53,7 +53,7 @@ typedef struct VFIOPlatformDevice {
     VFIORegion **regions;
     QLIST_HEAD(, VFIOINTp) intp_list; /* list of IRQs */
     /* queue of pending IRQs */
-    QSIMPLEQ_HEAD(pending_intp_queue, VFIOINTp) pending_intp_queue;
+    QSIMPLEQ_HEAD(, VFIOINTp) pending_intp_queue;
     char *compat; /* DT compatible values, separated by NUL */
     unsigned int num_compat; /* number of compatible values */
     uint32_t mmap_timeout; /* delay to re-enable mmaps after interrupt */
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 1396f53e5b..62aef77b87 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -375,9 +375,9 @@ struct CPUState {
     QTAILQ_ENTRY(CPUState) node;
 
     /* ice debug support */
-    QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints;
+    QTAILQ_HEAD(, CPUBreakpoint) breakpoints;
 
-    QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints;
+    QTAILQ_HEAD(, CPUWatchpoint) watchpoints;
     CPUWatchpoint *watchpoint_hit;
 
     void *opaque;
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 97d8d9d0d5..a6d1cd190f 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -412,8 +412,6 @@ struct kvm_sw_breakpoint {
     QTAILQ_ENTRY(kvm_sw_breakpoint) entry;
 };
 
-QTAILQ_HEAD(kvm_sw_breakpoint_head, kvm_sw_breakpoint);
-
 struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *cpu,
                                                  target_ulong pc);
 
diff --git a/include/sysemu/rng.h b/include/sysemu/rng.h
index 45629c4c53..27b37da05d 100644
--- a/include/sysemu/rng.h
+++ b/include/sysemu/rng.h
@@ -57,7 +57,7 @@ struct RngBackend
 
     /*< protected >*/
     bool opened;
-    QSIMPLEQ_HEAD(requests, RngRequest) requests;
+    QSIMPLEQ_HEAD(, RngRequest) requests;
 };
 
 
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 5bccd2e243..4cff9e1a31 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2844,7 +2844,7 @@ struct elf_note_info {
     struct target_elf_prstatus *prstatus;  /* NT_PRSTATUS */
     struct target_elf_prpsinfo *psinfo;    /* NT_PRPSINFO */
 
-    QTAILQ_HEAD(thread_list_head, elf_thread_status) thread_list;
+    QTAILQ_HEAD(, elf_thread_status) thread_list;
 #if 0
     /*
      * Current version of ELF coredump doesn't support
diff --git a/memory.c b/memory.c
index 5759f74034..195c5cf639 100644
--- a/memory.c
+++ b/memory.c
@@ -2795,7 +2795,7 @@ struct MemoryRegionList {
     QTAILQ_ENTRY(MemoryRegionList) mrqueue;
 };
 
-typedef QTAILQ_HEAD(mrqueue, MemoryRegionList) MemoryRegionListHead;
+typedef QTAILQ_HEAD(, MemoryRegionList) MemoryRegionListHead;
 
 #define MR_SIZE(size) (int128_nz(size) ? (hwaddr)int128_get64( \
                            int128_sub((size), int128_one())) : 0)
diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c
index 5e90f44c2f..6426151e4f 100644
--- a/migration/block-dirty-bitmap.c
+++ b/migration/block-dirty-bitmap.c
@@ -116,7 +116,7 @@ typedef struct DirtyBitmapMigBitmapState {
 } DirtyBitmapMigBitmapState;
 
 typedef struct DirtyBitmapMigState {
-    QSIMPLEQ_HEAD(dbms_list, DirtyBitmapMigBitmapState) dbms_list;
+    QSIMPLEQ_HEAD(, DirtyBitmapMigBitmapState) dbms_list;
 
     bool bulk_completed;
     bool no_bitmaps;
diff --git a/migration/block.c b/migration/block.c
index 4c04d937b1..0e24e18d13 100644
--- a/migration/block.c
+++ b/migration/block.c
@@ -93,12 +93,12 @@ typedef struct BlkMigBlock {
 } BlkMigBlock;
 
 typedef struct BlkMigState {
-    QSIMPLEQ_HEAD(bmds_list, BlkMigDevState) bmds_list;
+    QSIMPLEQ_HEAD(, BlkMigDevState) bmds_list;
     int64_t total_sector_sum;
     bool zero_blocks;
 
     /* Protected by lock.  */
-    QSIMPLEQ_HEAD(blk_list, BlkMigBlock) blk_list;
+    QSIMPLEQ_HEAD(, BlkMigBlock) blk_list;
     int submitted;
     int read_done;
 
diff --git a/migration/ram.c b/migration/ram.c
index 7e7deec4d8..1849979fed 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -322,7 +322,7 @@ struct RAMState {
     RAMBlock *last_req_rb;
     /* Queue of outstanding page requests from the destination */
     QemuMutex src_page_req_mutex;
-    QSIMPLEQ_HEAD(src_page_requests, RAMSrcPageRequest) src_page_requests;
+    QSIMPLEQ_HEAD(, RAMSrcPageRequest) src_page_requests;
 };
 typedef struct RAMState RAMState;
 
diff --git a/monitor.c b/monitor.c
index d39390c2f2..b8bdb98ba7 100644
--- a/monitor.c
+++ b/monitor.c
@@ -266,11 +266,11 @@ typedef struct QMPRequest QMPRequest;
 /* Protects mon_list, monitor_qapi_event_state.  */
 static QemuMutex monitor_lock;
 static GHashTable *monitor_qapi_event_state;
-static QTAILQ_HEAD(mon_list, Monitor) mon_list;
+static QTAILQ_HEAD(, Monitor) mon_list;
 
 /* Protects mon_fdsets */
 static QemuMutex mon_fdsets_lock;
-static QLIST_HEAD(mon_fdsets, MonFdset) mon_fdsets;
+static QLIST_HEAD(, MonFdset) mon_fdsets;
 
 static int mon_refcount;
 
diff --git a/net/queue.c b/net/queue.c
index 9c32abdb8f..61276ca4be 100644
--- a/net/queue.c
+++ b/net/queue.c
@@ -55,7 +55,7 @@ struct NetQueue {
     uint32_t nq_count;
     NetQueueDeliverFunc *deliver;
 
-    QTAILQ_HEAD(packets, NetPacket) packets;
+    QTAILQ_HEAD(, NetPacket) packets;
 
     unsigned delivering : 1;
 };
diff --git a/net/slirp.c b/net/slirp.c
index f6dc03963a..38ae65e4a9 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -85,7 +85,7 @@ typedef struct SlirpState {
 } SlirpState;
 
 static struct slirp_config_str *slirp_configs;
-static QTAILQ_HEAD(slirp_stacks, SlirpState) slirp_stacks =
+static QTAILQ_HEAD(, SlirpState) slirp_stacks =
     QTAILQ_HEAD_INITIALIZER(slirp_stacks);
 
 static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp);
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 322edf51eb..ab2fc4eb8b 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -47,7 +47,7 @@ static const uint8_t special_ethaddr[ETH_ALEN] = {
 
 u_int curtime;
 
-static QTAILQ_HEAD(slirp_instances, Slirp) slirp_instances =
+static QTAILQ_HEAD(, Slirp) slirp_instances =
     QTAILQ_HEAD_INITIALIZER(slirp_instances);
 
 static struct in_addr dns_addr;
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 44dd0ce6ce..e00ccf9c98 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -206,7 +206,7 @@ typedef struct KVMDevice {
     int dev_fd;
 } KVMDevice;
 
-static QSLIST_HEAD(kvm_devices_head, KVMDevice) kvm_devices_head;
+static QSLIST_HEAD(, KVMDevice) kvm_devices_head;
 
 static void kvm_arm_devlistener_add(MemoryListener *listener,
                                     MemoryRegionSection *section)
diff --git a/target/i386/hax-mem.c b/target/i386/hax-mem.c
index 5c37e94caa..6bb5a24917 100644
--- a/target/i386/hax-mem.c
+++ b/target/i386/hax-mem.c
@@ -56,7 +56,7 @@ typedef struct HAXMapping {
  * send to the kernel only the removal of the pages from the MMIO hole after
  * having computed locally the result of the deletion and additions.
  */
-static QTAILQ_HEAD(HAXMappingListHead, HAXMapping) mappings =
+static QTAILQ_HEAD(, HAXMapping) mappings =
     QTAILQ_HEAD_INITIALIZER(mappings);
 
 /**
diff --git a/tcg/tcg.h b/tcg/tcg.h
index f4efbaa680..1e9c87b46c 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -704,7 +704,7 @@ struct TCGContext {
 
     /* These structures are private to tcg-target.inc.c.  */
 #ifdef TCG_TARGET_NEED_LDST_LABELS
-    QSIMPLEQ_HEAD(ldst_labels, TCGLabelQemuLdst) ldst_labels;
+    QSIMPLEQ_HEAD(, TCGLabelQemuLdst) ldst_labels;
 #endif
 #ifdef TCG_TARGET_NEED_POOL_LABELS
     struct TCGLabelPoolData *pool_labels;
diff --git a/tests/test-rcu-list.c b/tests/test-rcu-list.c
index 2e6f70bd59..6f076473e0 100644
--- a/tests/test-rcu-list.c
+++ b/tests/test-rcu-list.c
@@ -108,7 +108,7 @@ static void reclaim_list_el(struct rcu_head *prcu)
 }
 
 #if TEST_LIST_TYPE == 1
-static QLIST_HEAD(q_list_head, list_element) Q_list_head;
+static QLIST_HEAD(, list_element) Q_list_head;
 
 #define TEST_NAME "qlist"
 #define TEST_LIST_REMOVE_RCU        QLIST_REMOVE_RCU
diff --git a/vl.c b/vl.c
index f6a6193428..4431ae6e99 100644
--- a/vl.c
+++ b/vl.c
@@ -1529,7 +1529,7 @@ struct vm_change_state_entry {
     QLIST_ENTRY (vm_change_state_entry) entries;
 };
 
-static QLIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head;
+static QLIST_HEAD(, vm_change_state_entry) vm_change_state_head;
 
 VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
                                                      void *opaque)
-- 
2.19.2

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

* [Qemu-devel] [PATCH 3/6] qemu/queue.h: typedef QTAILQ heads
  2018-12-06 23:23 [Qemu-devel] [PATCH for-4.0 0/6] qemu/queue.h usage cleanup, improved QTAILQ API Paolo Bonzini
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 1/6] qemu/queue.h: do not access tqe_prev directly Paolo Bonzini
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 2/6] qemu/queue.h: leave head structs anonymous unless necessary Paolo Bonzini
@ 2018-12-06 23:23 ` Paolo Bonzini
  2018-12-07  7:30   ` Markus Armbruster
  2018-12-07 10:15   ` Philippe Mathieu-Daudé
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 4/6] qemu/queue.h: reimplement QTAILQ without pointer-to-pointers Paolo Bonzini
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 16+ messages in thread
From: Paolo Bonzini @ 2018-12-06 23:23 UTC (permalink / raw)
  To: qemu-devel

This will be needed when we change the QTAILQ head and elem structs
to unions.  However, it is also consistent with the usage elsewhere
in QEMU for other list head structs (see for example FsMountList).

Note that most QTAILQs only need their name in order to do backwards
walks.  Those do not break with the struct->union change, and anyway
the change will also remove the need to name heads when doing backwards
walks, so those are not touched here.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 exec.c            |  3 ++-
 include/qom/cpu.h |  5 +++--
 ui/input.c        | 14 ++++++++------
 3 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/exec.c b/exec.c
index b6b2007f27..a629c98eb5 100644
--- a/exec.c
+++ b/exec.c
@@ -94,7 +94,8 @@ int target_page_bits;
 bool target_page_bits_decided;
 #endif
 
-struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
+CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
+
 /* current CPU in the current thread. It is only valid inside
    cpu_exec() */
 __thread CPUState *current_cpu;
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 62aef77b87..4662a205c1 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -435,8 +435,9 @@ struct CPUState {
     GArray *iommu_notifiers;
 };
 
-QTAILQ_HEAD(CPUTailQ, CPUState);
-extern struct CPUTailQ cpus;
+typedef QTAILQ_HEAD(CPUTailQ, CPUState) CPUTailQ;
+extern CPUTailQ cpus;
+
 #define first_cpu        QTAILQ_FIRST_RCU(&cpus)
 #define CPU_NEXT(cpu)    QTAILQ_NEXT_RCU(cpu, node)
 #define CPU_FOREACH(cpu) QTAILQ_FOREACH_RCU(cpu, &cpus, node)
diff --git a/ui/input.c b/ui/input.c
index 7c9a4109c4..35c7964f64 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -19,6 +19,9 @@ struct QemuInputHandlerState {
 };
 
 typedef struct QemuInputEventQueue QemuInputEventQueue;
+typedef QTAILQ_HEAD(QemuInputEventQueueHead, QemuInputEventQueue)
+    QemuInputEventQueueHead;
+
 struct QemuInputEventQueue {
     enum {
         QEMU_INPUT_QUEUE_DELAY = 1,
@@ -37,8 +40,7 @@ static QTAILQ_HEAD(, QemuInputHandlerState) handlers =
 static NotifierList mouse_mode_notifiers =
     NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers);
 
-static QTAILQ_HEAD(QemuInputEventQueueHead, QemuInputEventQueue) kbd_queue =
-    QTAILQ_HEAD_INITIALIZER(kbd_queue);
+static QemuInputEventQueueHead kbd_queue = QTAILQ_HEAD_INITIALIZER(kbd_queue);
 static QEMUTimer *kbd_timer;
 static uint32_t kbd_default_delay_ms = 10;
 static uint32_t queue_count;
@@ -257,7 +259,7 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt)
 
 static void qemu_input_queue_process(void *opaque)
 {
-    struct QemuInputEventQueueHead *queue = opaque;
+    QemuInputEventQueueHead *queue = opaque;
     QemuInputEventQueue *item;
 
     g_assert(!QTAILQ_EMPTY(queue));
@@ -288,7 +290,7 @@ static void qemu_input_queue_process(void *opaque)
     }
 }
 
-static void qemu_input_queue_delay(struct QemuInputEventQueueHead *queue,
+static void qemu_input_queue_delay(QemuInputEventQueueHead *queue,
                                    QEMUTimer *timer, uint32_t delay_ms)
 {
     QemuInputEventQueue *item = g_new0(QemuInputEventQueue, 1);
@@ -306,7 +308,7 @@ static void qemu_input_queue_delay(struct QemuInputEventQueueHead *queue,
     }
 }
 
-static void qemu_input_queue_event(struct QemuInputEventQueueHead *queue,
+static void qemu_input_queue_event(QemuInputEventQueueHead *queue,
                                    QemuConsole *src, InputEvent *evt)
 {
     QemuInputEventQueue *item = g_new0(QemuInputEventQueue, 1);
@@ -318,7 +320,7 @@ static void qemu_input_queue_event(struct QemuInputEventQueueHead *queue,
     queue_count++;
 }
 
-static void qemu_input_queue_sync(struct QemuInputEventQueueHead *queue)
+static void qemu_input_queue_sync(QemuInputEventQueueHead *queue)
 {
     QemuInputEventQueue *item = g_new0(QemuInputEventQueue, 1);
 
-- 
2.19.2

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

* [Qemu-devel] [PATCH 4/6] qemu/queue.h: reimplement QTAILQ without pointer-to-pointers
  2018-12-06 23:23 [Qemu-devel] [PATCH for-4.0 0/6] qemu/queue.h usage cleanup, improved QTAILQ API Paolo Bonzini
                   ` (2 preceding siblings ...)
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 3/6] qemu/queue.h: typedef QTAILQ heads Paolo Bonzini
@ 2018-12-06 23:23 ` Paolo Bonzini
  2018-12-07  9:22   ` Markus Armbruster
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 5/6] qemu/queue.h: simplify reverse access to QTAILQ Paolo Bonzini
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 6/6] checkpatch: warn about queue/queue.h head structs that are not typedef-ed Paolo Bonzini
  5 siblings, 1 reply; 16+ messages in thread
From: Paolo Bonzini @ 2018-12-06 23:23 UTC (permalink / raw)
  To: qemu-devel

QTAILQ is a doubly linked list, with a pointer-to-pointer to the last
element from the head, and the previous element from each node.

But if you squint enough, QTAILQ becomes a combination of a singly-linked
forwards list, and another singly-linked list which goes backwards and
is circular.  This is the idea that lets QTAILQ implement reverse
iteration: only, because the backwards list points inside the node,
accessing the previous element needs to go two steps back and one
forwards.

What this patch does is implement it in these terms, without actually
changing the in-memory layout at all.  The coexistence of the two lists
is realized by making QTAILQ_HEAD and QTAILQ_ENTRY unions of the forwards
pointer and a generic QTailQLink node.  Thq QTailQLink can walk the list in
both directions; the union is needed so that the forwards pointer can
have the correct type, as a sort of poor man's template.  While there
are other ways to get the same layout without a union, this one has
the advantage of simpler operation in the debugger, because the fields
tqh_first and tqe_next still exist as before the patch.  Those fields are
also used by scripts/qemugdb/mtree.py, so it's a good idea to preserve them.

The advantage of the new representation is that the two-back-one-forward
dance done by backwards accesses can be done all while operating on
QTailQLinks.  No casting to the head struct is needed anymore because,
even though the QTailQLink's forward pointer is a void *, we can use
typeof to recover the correct type.  This patch only changes the
implementation, not the interface.  The next patch will remove the head
struct name from the backwards visit macros.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/queue.h       | 143 ++++++++++++++++---------------------
 include/qemu/rcu_queue.h   |  45 ++++++------
 scripts/cocci-macro-file.h |  24 ++-----
 3 files changed, 93 insertions(+), 119 deletions(-)

diff --git a/include/qemu/queue.h b/include/qemu/queue.h
index ac418efc43..cb1bd6327c 100644
--- a/include/qemu/queue.h
+++ b/include/qemu/queue.h
@@ -346,77 +346,80 @@ struct {                                                                \
 #define QSIMPLEQ_FIRST(head)        ((head)->sqh_first)
 #define QSIMPLEQ_NEXT(elm, field)   ((elm)->field.sqe_next)
 
+typedef struct QTailQLink {
+    void *tql_next;
+    struct QTailQLink *tql_prev;
+} QTailQLink;
 
 /*
- * Tail queue definitions.
+ * Tail queue definitions.  The union acts as a poor man template, as if
+ * it were QTailQLink<type>.
  */
-#define Q_TAILQ_HEAD(name, type, qual)                                  \
-struct name {                                                           \
-        qual type *tqh_first;           /* first element */             \
-        qual type *qual *tqh_last;      /* addr of last next element */ \
+#define QTAILQ_HEAD(name, type)                                         \
+union name {                                                            \
+        struct type *tqh_first;       /* first element */               \
+        QTailQLink tqh_circ;          /* link for circular backwards list */ \
 }
-#define QTAILQ_HEAD(name, type)  Q_TAILQ_HEAD(name, struct type,)
 
 #define QTAILQ_HEAD_INITIALIZER(head)                                   \
-        { NULL, &(head).tqh_first }
+        { .tqh_circ = { NULL, &(head).tqh_circ } }
 
-#define Q_TAILQ_ENTRY(type, qual)                                       \
-struct {                                                                \
-        qual type *tqe_next;            /* next element */              \
-        qual type *qual *tqe_prev;      /* address of previous next element */\
+#define QTAILQ_ENTRY(type)                                              \
+union {                                                                 \
+        struct type *tqe_next;        /* next element */                \
+        QTailQLink tqe_circ;          /* link for circular backwards list */ \
 }
-#define QTAILQ_ENTRY(type)       Q_TAILQ_ENTRY(struct type,)
 
 /*
  * Tail queue functions.
  */
 #define QTAILQ_INIT(head) do {                                          \
         (head)->tqh_first = NULL;                                       \
-        (head)->tqh_last = &(head)->tqh_first;                          \
+        (head)->tqh_circ.tql_prev = &(head)->tqh_circ;                  \
 } while (/*CONSTCOND*/0)
 
 #define QTAILQ_INSERT_HEAD(head, elm, field) do {                       \
         if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)        \
-                (head)->tqh_first->field.tqe_prev =                     \
-                    &(elm)->field.tqe_next;                             \
+            (head)->tqh_first->field.tqe_circ.tql_prev =                \
+                &(elm)->field.tqe_circ;                                 \
         else                                                            \
-                (head)->tqh_last = &(elm)->field.tqe_next;              \
+            (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;         \
         (head)->tqh_first = (elm);                                      \
-        (elm)->field.tqe_prev = &(head)->tqh_first;                     \
+        (elm)->field.tqe_circ.tql_prev = &(head)->tqh_circ;             \
 } while (/*CONSTCOND*/0)
 
 #define QTAILQ_INSERT_TAIL(head, elm, field) do {                       \
         (elm)->field.tqe_next = NULL;                                   \
-        (elm)->field.tqe_prev = (head)->tqh_last;                       \
-        *(head)->tqh_last = (elm);                                      \
-        (head)->tqh_last = &(elm)->field.tqe_next;                      \
+        (elm)->field.tqe_circ.tql_prev = (head)->tqh_circ.tql_prev;     \
+        (head)->tqh_circ.tql_prev->tql_next = (elm);                    \
+        (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;             \
 } while (/*CONSTCOND*/0)
 
 #define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do {             \
         if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
-                (elm)->field.tqe_next->field.tqe_prev =                 \
-                    &(elm)->field.tqe_next;                             \
+            (elm)->field.tqe_next->field.tqe_circ.tql_prev =            \
+                &(elm)->field.tqe_circ;                                 \
         else                                                            \
-                (head)->tqh_last = &(elm)->field.tqe_next;              \
+            (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;         \
         (listelm)->field.tqe_next = (elm);                              \
-        (elm)->field.tqe_prev = &(listelm)->field.tqe_next;             \
+        (elm)->field.tqe_circ.tql_prev = &(listelm)->field.tqe_circ;    \
 } while (/*CONSTCOND*/0)
 
-#define QTAILQ_INSERT_BEFORE(listelm, elm, field) do {                  \
-        (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
-        (elm)->field.tqe_next = (listelm);                              \
-        *(listelm)->field.tqe_prev = (elm);                             \
-        (listelm)->field.tqe_prev = &(elm)->field.tqe_next;             \
+#define QTAILQ_INSERT_BEFORE(listelm, elm, field) do {                       \
+        (elm)->field.tqe_circ.tql_prev = (listelm)->field.tqe_circ.tql_prev; \
+        (elm)->field.tqe_next = (listelm);                                   \
+        (listelm)->field.tqe_circ.tql_prev->tql_next = (elm);                \
+        (listelm)->field.tqe_circ.tql_prev = &(elm)->field.tqe_circ;         \
 } while (/*CONSTCOND*/0)
 
 #define QTAILQ_REMOVE(head, elm, field) do {                            \
         if (((elm)->field.tqe_next) != NULL)                            \
-                (elm)->field.tqe_next->field.tqe_prev =                 \
-                    (elm)->field.tqe_prev;                              \
+            (elm)->field.tqe_next->field.tqe_circ.tql_prev =            \
+                (elm)->field.tqe_circ.tql_prev;                         \
         else                                                            \
-                (head)->tqh_last = (elm)->field.tqe_prev;               \
-        *(elm)->field.tqe_prev = (elm)->field.tqe_next;                 \
-        (elm)->field.tqe_prev = NULL;                                   \
+            (head)->tqh_circ.tql_prev = (elm)->field.tqe_circ.tql_prev; \
+        (elm)->field.tqe_circ.tql_prev->tql_next = (elm)->field.tqe_next; \
+        (elm)->field.tqe_circ.tql_prev = NULL;                          \
 } while (/*CONSTCOND*/0)
 
 #define QTAILQ_FOREACH(var, head, field)                                \
@@ -430,13 +433,13 @@ struct {                                                                \
                 (var) = (next_var))
 
 #define QTAILQ_FOREACH_REVERSE(var, head, headname, field)              \
-        for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));    \
+        for ((var) = QTAILQ_LAST(head, headname);                       \
                 (var);                                                  \
-                (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
+                (var) = QTAILQ_PREV(var, headname, field))
 
 #define QTAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, prev_var) \
-        for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
-             (var) && ((prev_var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)), 1); \
+        for ((var) = QTAILQ_LAST(head, headname);                       \
+             (var) && ((prev_var) = QTAILQ_PREV(var, headname, field)); \
              (var) = (prev_var))
 
 /*
@@ -445,71 +448,49 @@ struct {                                                                \
 #define QTAILQ_EMPTY(head)               ((head)->tqh_first == NULL)
 #define QTAILQ_FIRST(head)               ((head)->tqh_first)
 #define QTAILQ_NEXT(elm, field)          ((elm)->field.tqe_next)
-#define QTAILQ_IN_USE(elm, field)        ((elm)->field.tqe_prev != NULL)
+#define QTAILQ_IN_USE(elm, field)        ((elm)->field.tqe_circ.tql_prev != NULL)
 
+#define QTAILQ_LINK_PREV(link)                                          \
+        ((link).tql_prev->tql_prev->tql_next)
 #define QTAILQ_LAST(head, headname) \
-        (*(((struct headname *)((head)->tqh_last))->tqh_last))
+        ((typeof((head)->tqh_first)) QTAILQ_LINK_PREV((head)->tqh_circ))
 #define QTAILQ_PREV(elm, headname, field) \
-        (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+        ((typeof((elm)->field.tqe_next)) QTAILQ_LINK_PREV((elm)->field.tqe_circ))
 
 #define field_at_offset(base, offset, type)                                    \
-        ((type) (((char *) (base)) + (offset)))
-
-typedef struct DUMMY_Q_ENTRY DUMMY_Q_ENTRY;
-typedef struct DUMMY_Q DUMMY_Q;
-
-struct DUMMY_Q_ENTRY {
-        QTAILQ_ENTRY(DUMMY_Q_ENTRY) next;
-};
-
-struct DUMMY_Q {
-        QTAILQ_HEAD(DUMMY_Q_HEAD, DUMMY_Q_ENTRY) head;
-};
-
-#define dummy_q ((DUMMY_Q *) 0)
-#define dummy_qe ((DUMMY_Q_ENTRY *) 0)
+        ((type *) (((char *) (base)) + (offset)))
 
 /*
- * Offsets of layout of a tail queue head.
- */
-#define QTAILQ_FIRST_OFFSET (offsetof(typeof(dummy_q->head), tqh_first))
-#define QTAILQ_LAST_OFFSET  (offsetof(typeof(dummy_q->head), tqh_last))
-/*
- * Raw access of elements of a tail queue
+ * Raw access of elements of a tail queue head.  Offsets are all zero
+ * because it's a union.
  */
 #define QTAILQ_RAW_FIRST(head)                                                 \
-        (*field_at_offset(head, QTAILQ_FIRST_OFFSET, void **))
-#define QTAILQ_RAW_TQH_LAST(head)                                              \
-        (*field_at_offset(head, QTAILQ_LAST_OFFSET, void ***))
-
-/*
- * Offsets of layout of a tail queue element.
- */
-#define QTAILQ_NEXT_OFFSET (offsetof(typeof(dummy_qe->next), tqe_next))
-#define QTAILQ_PREV_OFFSET (offsetof(typeof(dummy_qe->next), tqe_prev))
+        field_at_offset(head, 0, void *)
+#define QTAILQ_RAW_TQH_CIRC(head)                                              \
+        field_at_offset(head, 0, QTailQLink)
 
 /*
  * Raw access of elements of a tail entry
  */
 #define QTAILQ_RAW_NEXT(elm, entry)                                            \
-        (*field_at_offset(elm, entry + QTAILQ_NEXT_OFFSET, void **))
-#define QTAILQ_RAW_TQE_PREV(elm, entry)                                        \
-        (*field_at_offset(elm, entry + QTAILQ_PREV_OFFSET, void ***))
+        field_at_offset(elm, entry, void *)
+#define QTAILQ_RAW_TQE_CIRC(elm, entry)                                        \
+        field_at_offset(elm, entry, QTailQLink)
 /*
- * Tail queue tranversal using pointer arithmetic.
+ * Tail queue traversal using pointer arithmetic.
  */
 #define QTAILQ_RAW_FOREACH(elm, head, entry)                                   \
-        for ((elm) = QTAILQ_RAW_FIRST(head);                                   \
+        for ((elm) = *QTAILQ_RAW_FIRST(head);                                  \
              (elm);                                                            \
-             (elm) = QTAILQ_RAW_NEXT(elm, entry))
+             (elm) = *QTAILQ_RAW_NEXT(elm, entry))
 /*
  * Tail queue insertion using pointer arithmetic.
  */
-#define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) do {                          \
-        QTAILQ_RAW_NEXT(elm, entry) = NULL;                                    \
-        QTAILQ_RAW_TQE_PREV(elm, entry) = QTAILQ_RAW_TQH_LAST(head);           \
-        *QTAILQ_RAW_TQH_LAST(head) = (elm);                                    \
-        QTAILQ_RAW_TQH_LAST(head) = &QTAILQ_RAW_NEXT(elm, entry);              \
+#define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) do {                           \
+        *QTAILQ_RAW_NEXT(elm, entry) = NULL;                                    \
+        QTAILQ_RAW_TQE_CIRC(elm, entry)->tql_prev = QTAILQ_RAW_TQH_CIRC(head)->tql_prev; \
+        QTAILQ_RAW_TQH_CIRC(head)->tql_prev->tql_next = (elm);                  \
+        QTAILQ_RAW_TQH_CIRC(head)->tql_prev = QTAILQ_RAW_TQE_CIRC(elm, entry);  \
 } while (/*CONSTCOND*/0)
 
 #endif /* QEMU_SYS_QUEUE_H */
diff --git a/include/qemu/rcu_queue.h b/include/qemu/rcu_queue.h
index 904b3372dc..2bee5dff80 100644
--- a/include/qemu/rcu_queue.h
+++ b/include/qemu/rcu_queue.h
@@ -206,47 +206,50 @@ extern "C" {
 #define QTAILQ_INSERT_HEAD_RCU(head, elm, field) do {                   \
     (elm)->field.tqe_next = (head)->tqh_first;                          \
     if ((elm)->field.tqe_next != NULL) {                                \
-        (head)->tqh_first->field.tqe_prev = &(elm)->field.tqe_next;     \
+        (head)->tqh_first->field.tqe_circ.tql_prev =                    \
+            &(elm)->field.tqe_circ;                                     \
     } else {                                                            \
-        (head)->tqh_last = &(elm)->field.tqe_next;                      \
+        (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;             \
     }                                                                   \
     atomic_rcu_set(&(head)->tqh_first, (elm));                          \
-    (elm)->field.tqe_prev = &(head)->tqh_first;                         \
+    (elm)->field.tqe_circ.tql_prev = &(head)->tqh_circ;                 \
 } while (/*CONSTCOND*/0)
 
-#define QTAILQ_INSERT_TAIL_RCU(head, elm, field) do {               \
-    (elm)->field.tqe_next = NULL;                                   \
-    (elm)->field.tqe_prev = (head)->tqh_last;                       \
-    atomic_rcu_set((head)->tqh_last, (elm));                        \
-    (head)->tqh_last = &(elm)->field.tqe_next;                      \
+#define QTAILQ_INSERT_TAIL_RCU(head, elm, field) do {                   \
+    (elm)->field.tqe_next = NULL;                                       \
+    (elm)->field.tqe_circ.tql_prev = (head)->tqh_circ.tql_prev;         \
+    atomic_rcu_set(&(head)->tqh_circ.tql_prev->tql_next, (elm));        \
+    (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;                 \
 } while (/*CONSTCOND*/0)
 
 #define QTAILQ_INSERT_AFTER_RCU(head, listelm, elm, field) do {         \
     (elm)->field.tqe_next = (listelm)->field.tqe_next;                  \
     if ((elm)->field.tqe_next != NULL) {                                \
-        (elm)->field.tqe_next->field.tqe_prev = &(elm)->field.tqe_next; \
+        (elm)->field.tqe_next->field.tqe_circ.tql_prev =                \
+            &(elm)->field.tqe_circ;                                     \
     } else {                                                            \
-        (head)->tqh_last = &(elm)->field.tqe_next;                      \
+        (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;             \
     }                                                                   \
     atomic_rcu_set(&(listelm)->field.tqe_next, (elm));                  \
-    (elm)->field.tqe_prev = &(listelm)->field.tqe_next;                 \
+    (elm)->field.tqe_circ.tql_prev = &(listelm)->field.tqe_circ;        \
 } while (/*CONSTCOND*/0)
 
-#define QTAILQ_INSERT_BEFORE_RCU(listelm, elm, field) do {          \
-    (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
-    (elm)->field.tqe_next = (listelm);                              \
-    atomic_rcu_set((listelm)->field.tqe_prev, (elm));               \
-    (listelm)->field.tqe_prev = &(elm)->field.tqe_next;             \
-    } while (/*CONSTCOND*/0)
+#define QTAILQ_INSERT_BEFORE_RCU(listelm, elm, field) do {                \
+    (elm)->field.tqe_circ.tql_prev = (listelm)->field.tqe_circ.tql_prev;  \
+    (elm)->field.tqe_next = (listelm);                                    \
+    atomic_rcu_set(&(listelm)->field.tqe_circ.tql_prev->tql_next, (elm)); \
+    (listelm)->field.tqe_circ.tql_prev = &(elm)->field.tqe_circ;          \
+} while (/*CONSTCOND*/0)
 
 #define QTAILQ_REMOVE_RCU(head, elm, field) do {                        \
     if (((elm)->field.tqe_next) != NULL) {                              \
-        (elm)->field.tqe_next->field.tqe_prev = (elm)->field.tqe_prev;  \
+        (elm)->field.tqe_next->field.tqe_circ.tql_prev =                \
+            (elm)->field.tqe_circ.tql_prev;                             \
     } else {                                                            \
-        (head)->tqh_last = (elm)->field.tqe_prev;                       \
+        (head)->tqh_circ.tql_prev = (elm)->field.tqe_circ.tql_prev;     \
     }                                                                   \
-    atomic_set((elm)->field.tqe_prev, (elm)->field.tqe_next);           \
-    (elm)->field.tqe_prev = NULL;                                       \
+    atomic_set(&(elm)->field.tqe_circ.tql_prev->tql_next, (elm)->field.tqe_next); \
+    (elm)->field.tqe_circ.tql_prev = NULL;                              \
 } while (/*CONSTCOND*/0)
 
 #define QTAILQ_FOREACH_RCU(var, head, field)                            \
diff --git a/scripts/cocci-macro-file.h b/scripts/cocci-macro-file.h
index 9f2e72e7e1..7f1006e97c 100644
--- a/scripts/cocci-macro-file.h
+++ b/scripts/cocci-macro-file.h
@@ -93,29 +93,19 @@ struct {                                                                \
 /*
  * Tail queue definitions.
  */
-#define Q_TAILQ_HEAD(name, type, qual)                                  \
-struct name {                                                           \
-        qual type *tqh_first;           /* first element */             \
-        qual type *qual *tqh_last;      /* addr of last next element */ \
-}
 #define QTAILQ_HEAD(name, type)                                         \
-struct name {                                                           \
-        type *tqh_first;      /* first element */                       \
-        type **tqh_last;      /* addr of last next element */           \
+union name {                                                            \
+        struct type *tqh_first;       /* first element */               \
+        QTailQLink tqh_circ;          /* link for last element */       \
 }
 
 #define QTAILQ_HEAD_INITIALIZER(head)                                   \
-        { NULL, &(head).tqh_first }
+        { .tqh_circ = { NULL, &(head).tqh_circ } }
 
-#define Q_TAILQ_ENTRY(type, qual)                                       \
-struct {                                                                \
-        qual type *tqe_next;            /* next element */              \
-        qual type *qual *tqe_prev;      /* address of previous next element */\
-}
 #define QTAILQ_ENTRY(type)                                              \
-struct {                                                                \
-        type *tqe_next;       /* next element */                        \
-        type **tqe_prev;      /* address of previous next element */    \
+union {                                                                 \
+        struct type *tqe_next;        /* next element */                \
+        QTailQLink tqe_circ;          /* link for prev element */       \
 }
 
 /* From glib */
-- 
2.19.2

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

* [Qemu-devel] [PATCH 5/6] qemu/queue.h: simplify reverse access to QTAILQ
  2018-12-06 23:23 [Qemu-devel] [PATCH for-4.0 0/6] qemu/queue.h usage cleanup, improved QTAILQ API Paolo Bonzini
                   ` (3 preceding siblings ...)
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 4/6] qemu/queue.h: reimplement QTAILQ without pointer-to-pointers Paolo Bonzini
@ 2018-12-06 23:23 ` Paolo Bonzini
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 6/6] checkpatch: warn about queue/queue.h head structs that are not typedef-ed Paolo Bonzini
  5 siblings, 0 replies; 16+ messages in thread
From: Paolo Bonzini @ 2018-12-06 23:23 UTC (permalink / raw)
  To: qemu-devel

The new definition of QTAILQ does not require passing the headname,
remove it.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpus-common.c                   |  2 +-
 dump.c                          |  2 +-
 hw/core/qdev.c                  |  4 ++--
 hw/scsi/scsi-bus.c              |  2 +-
 hw/usb/combined-packet.c        |  2 +-
 hw/usb/dev-mtp.c                |  4 ++--
 hw/usb/hcd-ehci.c               |  2 +-
 hw/usb/hcd-ehci.h               |  2 +-
 hw/usb/hcd-uhci.c               |  4 ++--
 include/exec/memory.h           |  2 +-
 include/hw/qdev-core.h          |  2 +-
 include/hw/usb.h                |  2 +-
 include/net/net.h               |  2 +-
 include/qemu/option_int.h       |  2 +-
 include/qemu/queue.h            | 16 ++++++++--------
 include/sysemu/memory_mapping.h |  2 +-
 memory.c                        | 17 ++++++-----------
 memory_mapping.c                |  2 +-
 net/filter.c                    |  2 +-
 net/net.c                       |  2 +-
 qga/commands-posix.c            |  2 +-
 tcg/tcg.c                       |  2 +-
 tcg/tcg.h                       |  4 ++--
 tests/libqos/malloc.c           |  2 +-
 tests/test-vmstate.c            |  8 ++++----
 ui/console.c                    |  4 ++--
 util/qemu-option.c              |  4 ++--
 27 files changed, 48 insertions(+), 53 deletions(-)

diff --git a/cpus-common.c b/cpus-common.c
index 98dd8c6ff1..3ca58c64e8 100644
--- a/cpus-common.c
+++ b/cpus-common.c
@@ -99,7 +99,7 @@ void cpu_list_remove(CPUState *cpu)
         return;
     }
 
-    assert(!(cpu_index_auto_assigned && cpu != QTAILQ_LAST(&cpus, CPUTailQ)));
+    assert(!(cpu_index_auto_assigned && cpu != QTAILQ_LAST(&cpus)));
 
     QTAILQ_REMOVE_RCU(&cpus, cpu, node);
     cpu->cpu_index = UNASSIGNED_CPU_INDEX;
diff --git a/dump.c b/dump.c
index 4ec94c5e25..ef1d8025c9 100644
--- a/dump.c
+++ b/dump.c
@@ -1557,7 +1557,7 @@ static void get_max_mapnr(DumpState *s)
 {
     GuestPhysBlock *last_block;
 
-    last_block = QTAILQ_LAST(&s->guest_phys_blocks.head, GuestPhysBlockHead);
+    last_block = QTAILQ_LAST(&s->guest_phys_blocks.head);
     s->max_mapnr = dump_paddr_to_pfn(s, last_block->target_end);
 }
 
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 6b3cc55b27..a7dd4bebd6 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -158,7 +158,7 @@ DeviceState *qdev_try_create(BusState *bus, const char *type)
     return dev;
 }
 
-static QTAILQ_HEAD(device_listeners, DeviceListener) device_listeners
+static QTAILQ_HEAD(, DeviceListener) device_listeners
     = QTAILQ_HEAD_INITIALIZER(device_listeners);
 
 enum ListenerDirection { Forward, Reverse };
@@ -177,7 +177,7 @@ enum ListenerDirection { Forward, Reverse };
             break;                                                \
         case Reverse:                                             \
             QTAILQ_FOREACH_REVERSE(_listener, &device_listeners,  \
-                                   device_listeners, link) {      \
+                                   link) {                        \
                 if (_listener->_callback) {                       \
                     _listener->_callback(_listener, ##_args);     \
                 }                                                 \
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 97cd167114..c480553083 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -1554,7 +1554,7 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun)
     BusChild *kid;
     SCSIDevice *target_dev = NULL;
 
-    QTAILQ_FOREACH_REVERSE(kid, &bus->qbus.children, ChildrenHead, sibling) {
+    QTAILQ_FOREACH_REVERSE(kid, &bus->qbus.children, sibling) {
         DeviceState *qdev = kid->child;
         SCSIDevice *dev = SCSI_DEVICE(qdev);
 
diff --git a/hw/usb/combined-packet.c b/hw/usb/combined-packet.c
index 01a7ed0848..fc98383d30 100644
--- a/hw/usb/combined-packet.c
+++ b/hw/usb/combined-packet.c
@@ -64,7 +64,7 @@ void usb_combined_input_packet_complete(USBDevice *dev, USBPacket *p)
 
     status = combined->first->status;
     actual_length = combined->first->actual_length;
-    short_not_ok = QTAILQ_LAST(&combined->packets, packets_head)->short_not_ok;
+    short_not_ok = QTAILQ_LAST(&combined->packets)->short_not_ok;
 
     QTAILQ_FOREACH_SAFE(p, &combined->packets, combined_entry, next) {
         if (!done) {
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 100b7171f4..c33d7d6b1f 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -191,7 +191,7 @@ struct MTPState {
 #ifdef CONFIG_INOTIFY1
     /* inotify descriptor */
     int          inotifyfd;
-    QTAILQ_HEAD(events, MTPMonEntry) events;
+    QTAILQ_HEAD(, MTPMonEntry) events;
 #endif
     /* Responder is expecting a write operation */
     bool write_pending;
@@ -1982,7 +1982,7 @@ static void usb_mtp_handle_data(USBDevice *dev, USBPacket *p)
     case EP_EVENT:
 #ifdef CONFIG_INOTIFY1
         if (!QTAILQ_EMPTY(&s->events)) {
-            struct MTPMonEntry *e = QTAILQ_LAST(&s->events, events);
+            struct MTPMonEntry *e = QTAILQ_LAST(&s->events);
             uint32_t handle;
             int len = sizeof(container) + sizeof(uint32_t);
 
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index e5acfc5ba5..a2105c8ab1 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1815,7 +1815,7 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
             break;
         case EHCI_ASYNC_INFLIGHT:
             /* Check if the guest has added new tds to the queue */
-            again = ehci_fill_queue(QTAILQ_LAST(&q->packets, pkts_head));
+            again = ehci_fill_queue(QTAILQ_LAST(&q->packets));
             /* Unfinished async handled packet, go horizontal */
             ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
             break;
diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h
index 0bc364b286..e4460aa1a8 100644
--- a/hw/usb/hcd-ehci.h
+++ b/hw/usb/hcd-ehci.h
@@ -247,7 +247,7 @@ struct EHCIQueue {
     uint32_t qtdaddr;      /* address QTD read from                */
     int last_pid;          /* pid of last packet executed          */
     USBDevice *dev;
-    QTAILQ_HEAD(pkts_head, EHCIPacket) packets;
+    QTAILQ_HEAD(, EHCIPacket) packets;
 };
 
 typedef QTAILQ_HEAD(EHCIQueueHead, EHCIQueue) EHCIQueueHead;
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 836b11f177..26f123ed78 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -99,7 +99,7 @@ struct UHCIQueue {
     UHCIState *uhci;
     USBEndpoint *ep;
     QTAILQ_ENTRY(UHCIQueue) next;
-    QTAILQ_HEAD(asyncs_head, UHCIAsync) asyncs;
+    QTAILQ_HEAD(, UHCIAsync) asyncs;
     int8_t    valid;
 };
 
@@ -837,7 +837,7 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
         }
         if (!async->done) {
             UHCI_TD last_td;
-            UHCIAsync *last = QTAILQ_LAST(&async->queue->asyncs, asyncs_head);
+            UHCIAsync *last = QTAILQ_LAST(&async->queue->asyncs);
             /*
              * While we are waiting for the current td to complete, the guest
              * may have added more tds to the queue. Note we re-read the td
diff --git a/include/exec/memory.h b/include/exec/memory.h
index ce930689cf..7353fa2ac6 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -445,7 +445,7 @@ struct AddressSpace {
 
     int ioeventfd_nb;
     struct MemoryRegionIoeventfd *ioeventfds;
-    QTAILQ_HEAD(memory_listeners_as, MemoryListener) listeners;
+    QTAILQ_HEAD(, MemoryListener) listeners;
     QTAILQ_ENTRY(AddressSpace) address_spaces_link;
 };
 
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index a24d0dd566..43f926f5eb 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -206,7 +206,7 @@ struct BusState {
     HotplugHandler *hotplug_handler;
     int max_index;
     bool realized;
-    QTAILQ_HEAD(ChildrenHead, BusChild) children;
+    QTAILQ_HEAD(, BusChild) children;
     QLIST_ENTRY(BusState) sibling;
 };
 
diff --git a/include/hw/usb.h b/include/hw/usb.h
index a5080adecc..f9431a0ebc 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -408,7 +408,7 @@ struct USBPacket {
 
 struct USBCombinedPacket {
     USBPacket *first;
-    QTAILQ_HEAD(packets_head, USBPacket) packets;
+    QTAILQ_HEAD(, USBPacket) packets;
     QEMUIOVector iov;
 };
 
diff --git a/include/net/net.h b/include/net/net.h
index ec13702dbf..643295d163 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -97,7 +97,7 @@ struct NetClientState {
     unsigned rxfilter_notify_enabled:1;
     int vring_enable;
     int vnet_hdr_len;
-    QTAILQ_HEAD(NetFilterHead, NetFilterState) filters;
+    QTAILQ_HEAD(, NetFilterState) filters;
 };
 
 typedef struct NICState {
diff --git a/include/qemu/option_int.h b/include/qemu/option_int.h
index 26b1d9e4d6..5dd9a5162d 100644
--- a/include/qemu/option_int.h
+++ b/include/qemu/option_int.h
@@ -47,7 +47,7 @@ struct QemuOpts {
     char *id;
     QemuOptsList *list;
     Location loc;
-    QTAILQ_HEAD(QemuOptHead, QemuOpt) head;
+    QTAILQ_HEAD(, QemuOpt) head;
     QTAILQ_ENTRY(QemuOpts) next;
 };
 
diff --git a/include/qemu/queue.h b/include/qemu/queue.h
index cb1bd6327c..c16d4d3d16 100644
--- a/include/qemu/queue.h
+++ b/include/qemu/queue.h
@@ -432,14 +432,14 @@ union {                                                                 \
                 (var) && ((next_var) = ((var)->field.tqe_next), 1);     \
                 (var) = (next_var))
 
-#define QTAILQ_FOREACH_REVERSE(var, head, headname, field)              \
-        for ((var) = QTAILQ_LAST(head, headname);                       \
+#define QTAILQ_FOREACH_REVERSE(var, head, field)                        \
+        for ((var) = QTAILQ_LAST(head);                                 \
                 (var);                                                  \
-                (var) = QTAILQ_PREV(var, headname, field))
+                (var) = QTAILQ_PREV(var, field))
 
-#define QTAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, prev_var) \
-        for ((var) = QTAILQ_LAST(head, headname);                       \
-             (var) && ((prev_var) = QTAILQ_PREV(var, headname, field)); \
+#define QTAILQ_FOREACH_REVERSE_SAFE(var, head, field, prev_var)         \
+        for ((var) = QTAILQ_LAST(head);                                 \
+             (var) && ((prev_var) = QTAILQ_PREV(var, field));           \
              (var) = (prev_var))
 
 /*
@@ -452,9 +452,9 @@ union {                                                                 \
 
 #define QTAILQ_LINK_PREV(link)                                          \
         ((link).tql_prev->tql_prev->tql_next)
-#define QTAILQ_LAST(head, headname) \
+#define QTAILQ_LAST(head)                                               \
         ((typeof((head)->tqh_first)) QTAILQ_LINK_PREV((head)->tqh_circ))
-#define QTAILQ_PREV(elm, headname, field) \
+#define QTAILQ_PREV(elm, field)                                         \
         ((typeof((elm)->field.tqe_next)) QTAILQ_LINK_PREV((elm)->field.tqe_circ))
 
 #define field_at_offset(base, offset, type)                                    \
diff --git a/include/sysemu/memory_mapping.h b/include/sysemu/memory_mapping.h
index 706152d533..58452457ce 100644
--- a/include/sysemu/memory_mapping.h
+++ b/include/sysemu/memory_mapping.h
@@ -36,7 +36,7 @@ typedef struct GuestPhysBlock {
 /* point-in-time snapshot of guest-visible physical mappings */
 typedef struct GuestPhysBlockList {
     unsigned num;
-    QTAILQ_HEAD(GuestPhysBlockHead, GuestPhysBlock) head;
+    QTAILQ_HEAD(, GuestPhysBlock) head;
 } GuestPhysBlockList;
 
 /* The physical and virtual address in the memory mapping are contiguous. */
diff --git a/memory.c b/memory.c
index 195c5cf639..61d66e4441 100644
--- a/memory.c
+++ b/memory.c
@@ -39,7 +39,7 @@ static bool memory_region_update_pending;
 static bool ioeventfd_update_pending;
 static bool global_dirty_log = false;
 
-static QTAILQ_HEAD(memory_listeners, MemoryListener) memory_listeners
+static QTAILQ_HEAD(, MemoryListener) memory_listeners
     = QTAILQ_HEAD_INITIALIZER(memory_listeners);
 
 static QTAILQ_HEAD(, AddressSpace) address_spaces
@@ -113,8 +113,7 @@ enum ListenerDirection { Forward, Reverse };
             }                                                           \
             break;                                                      \
         case Reverse:                                                   \
-            QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners,        \
-                                   memory_listeners, link) {            \
+            QTAILQ_FOREACH_REVERSE(_listener, &memory_listeners, link) { \
                 if (_listener->_callback) {                             \
                     _listener->_callback(_listener, ##_args);           \
                 }                                                       \
@@ -128,19 +127,17 @@ enum ListenerDirection { Forward, Reverse };
 #define MEMORY_LISTENER_CALL(_as, _callback, _direction, _section, _args...) \
     do {                                                                \
         MemoryListener *_listener;                                      \
-        struct memory_listeners_as *list = &(_as)->listeners;           \
                                                                         \
         switch (_direction) {                                           \
         case Forward:                                                   \
-            QTAILQ_FOREACH(_listener, list, link_as) {                  \
+            QTAILQ_FOREACH(_listener, &(_as)->listeners, link_as) {     \
                 if (_listener->_callback) {                             \
                     _listener->_callback(_listener, _section, ##_args); \
                 }                                                       \
             }                                                           \
             break;                                                      \
         case Reverse:                                                   \
-            QTAILQ_FOREACH_REVERSE(_listener, list, memory_listeners_as, \
-                                   link_as) {                           \
+            QTAILQ_FOREACH_REVERSE(_listener, &(_as)->listeners, link_as) { \
                 if (_listener->_callback) {                             \
                     _listener->_callback(_listener, _section, ##_args); \
                 }                                                       \
@@ -2691,8 +2688,7 @@ void memory_listener_register(MemoryListener *listener, AddressSpace *as)
 
     listener->address_space = as;
     if (QTAILQ_EMPTY(&memory_listeners)
-        || listener->priority >= QTAILQ_LAST(&memory_listeners,
-                                             memory_listeners)->priority) {
+        || listener->priority >= QTAILQ_LAST(&memory_listeners)->priority) {
         QTAILQ_INSERT_TAIL(&memory_listeners, listener, link);
     } else {
         QTAILQ_FOREACH(other, &memory_listeners, link) {
@@ -2704,8 +2700,7 @@ void memory_listener_register(MemoryListener *listener, AddressSpace *as)
     }
 
     if (QTAILQ_EMPTY(&as->listeners)
-        || listener->priority >= QTAILQ_LAST(&as->listeners,
-                                             memory_listeners)->priority) {
+        || listener->priority >= QTAILQ_LAST(&as->listeners)->priority) {
         QTAILQ_INSERT_TAIL(&as->listeners, listener, link_as);
     } else {
         QTAILQ_FOREACH(other, &as->listeners, link_as) {
diff --git a/memory_mapping.c b/memory_mapping.c
index 724dd0b417..e3ec70624f 100644
--- a/memory_mapping.c
+++ b/memory_mapping.c
@@ -223,7 +223,7 @@ static void guest_phys_blocks_region_add(MemoryListener *listener,
     if (!QTAILQ_EMPTY(&g->list->head)) {
         hwaddr predecessor_size;
 
-        predecessor = QTAILQ_LAST(&g->list->head, GuestPhysBlockHead);
+        predecessor = QTAILQ_LAST(&g->list->head);
         predecessor_size = predecessor->target_end - predecessor->target_start;
 
         /* the memory API guarantees monotonically increasing traversal */
diff --git a/net/filter.c b/net/filter.c
index c9f9e5fa08..28d1930db7 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -55,7 +55,7 @@ static NetFilterState *netfilter_next(NetFilterState *nf,
         next = QTAILQ_NEXT(nf, next);
     } else {
         /* reverse order */
-        next = QTAILQ_PREV(nf, NetFilterHead, next);
+        next = QTAILQ_PREV(nf, next);
     }
 
     return next;
diff --git a/net/net.c b/net/net.c
index 1f7d626197..3acbdccd61 100644
--- a/net/net.c
+++ b/net/net.c
@@ -563,7 +563,7 @@ static ssize_t filter_receive_iov(NetClientState *nc,
             }
         }
     } else {
-        QTAILQ_FOREACH_REVERSE(nf, &nc->filters, NetFilterHead, next) {
+        QTAILQ_FOREACH_REVERSE(nf, &nc->filters, next) {
             ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
                                          iovcnt, sent_cb);
             if (ret) {
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 1877976522..18a4724bc9 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1291,7 +1291,7 @@ int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,
     /* cannot risk guest agent blocking itself on a write in this state */
     ga_set_frozen(ga_state);
 
-    QTAILQ_FOREACH_REVERSE(mount, &mounts, FsMountList, next) {
+    QTAILQ_FOREACH_REVERSE(mount, &mounts, next) {
         /* To issue fsfreeze in the reverse order of mounts, check if the
          * mount is listed in the list here */
         if (has_mountpoints) {
diff --git a/tcg/tcg.c b/tcg/tcg.c
index e85133ef05..2e090937a9 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2269,7 +2269,7 @@ static void liveness_pass_1(TCGContext *s)
 
     tcg_la_func_end(s);
 
-    QTAILQ_FOREACH_REVERSE_SAFE(op, &s->ops, TCGOpHead, link, op_prev) {
+    QTAILQ_FOREACH_REVERSE_SAFE(op, &s->ops, link, op_prev) {
         int i, nb_iargs, nb_oargs;
         TCGOpcode opc_new, opc_new2;
         bool have_opc_new2;
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 1e9c87b46c..cbe43095cd 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -715,7 +715,7 @@ struct TCGContext {
     TCGTempSet free_temps[TCG_TYPE_COUNT * 2];
     TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */
 
-    QTAILQ_HEAD(TCGOpHead, TCGOp) ops, free_ops;
+    QTAILQ_HEAD(, TCGOp) ops, free_ops;
 
     /* Tells which temporary holds a given register.
        It does not take into account fixed registers */
@@ -843,7 +843,7 @@ static inline void tcg_set_insn_start_param(TCGOp *op, int arg, target_ulong v)
 /* The last op that was emitted.  */
 static inline TCGOp *tcg_last_op(void)
 {
-    return QTAILQ_LAST(&tcg_ctx->ops, TCGOpHead);
+    return QTAILQ_LAST(&tcg_ctx->ops);
 }
 
 /* Test for whether to terminate the TB for using too many opcodes.  */
diff --git a/tests/libqos/malloc.c b/tests/libqos/malloc.c
index ac05874b0a..f7bae47a08 100644
--- a/tests/libqos/malloc.c
+++ b/tests/libqos/malloc.c
@@ -104,7 +104,7 @@ static void mlist_coalesce(MemList *head, MemBlock *node)
 
     do {
         merge = 0;
-        left = QTAILQ_PREV(node, MemList, MLIST_ENTNAME);
+        left = QTAILQ_PREV(node, MLIST_ENTNAME);
         right = QTAILQ_NEXT(node, MLIST_ENTNAME);
 
         /* clowns to the left of me */
diff --git a/tests/test-vmstate.c b/tests/test-vmstate.c
index 37a7a93784..0ab29a8216 100644
--- a/tests/test-vmstate.c
+++ b/tests/test-vmstate.c
@@ -630,7 +630,7 @@ struct TestQtailqElement {
 
 typedef struct TestQtailq {
     int16_t  i16;
-    QTAILQ_HEAD(TestQtailqHead, TestQtailqElement) q;
+    QTAILQ_HEAD(, TestQtailqElement) q;
     int32_t  i32;
 } TestQtailq;
 
@@ -735,9 +735,9 @@ static void test_load_q(void)
     g_assert_cmpint(eof, ==, QEMU_VM_EOF);
 
     TestQtailqElement *qele_from = QTAILQ_FIRST(&obj_q.q);
-    TestQtailqElement *qlast_from = QTAILQ_LAST(&obj_q.q, TestQtailqHead);
+    TestQtailqElement *qlast_from = QTAILQ_LAST(&obj_q.q);
     TestQtailqElement *qele_to = QTAILQ_FIRST(&tgt.q);
-    TestQtailqElement *qlast_to = QTAILQ_LAST(&tgt.q, TestQtailqHead);
+    TestQtailqElement *qlast_to = QTAILQ_LAST(&tgt.q);
 
     while (1) {
         g_assert_cmpint(qele_to->b, ==, qele_from->b);
@@ -755,7 +755,7 @@ static void test_load_q(void)
     /* clean up */
     TestQtailqElement *qele;
     while (!QTAILQ_EMPTY(&tgt.q)) {
-        qele = QTAILQ_LAST(&tgt.q, TestQtailqHead);
+        qele = QTAILQ_LAST(&tgt.q);
         QTAILQ_REMOVE(&tgt.q, qele, next);
         free(qele);
         qele = NULL;
diff --git a/ui/console.c b/ui/console.c
index 3a285bae00..5a904e67d0 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -182,7 +182,7 @@ struct DisplayState {
 
 static DisplayState *display_state;
 static QemuConsole *active_console;
-static QTAILQ_HEAD(consoles_head, QemuConsole) consoles =
+static QTAILQ_HEAD(, QemuConsole) consoles =
     QTAILQ_HEAD_INITIALIZER(consoles);
 static bool cursor_visible_phase;
 static QEMUTimer *cursor_timer;
@@ -1303,7 +1303,7 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type,
         s->index = 0;
         QTAILQ_INSERT_TAIL(&consoles, s, next);
     } else if (console_type != GRAPHIC_CONSOLE || qdev_hotplug) {
-        QemuConsole *last = QTAILQ_LAST(&consoles, consoles_head);
+        QemuConsole *last = QTAILQ_LAST(&consoles);
         s->index = last->index + 1;
         QTAILQ_INSERT_TAIL(&consoles, s, next);
     } else {
diff --git a/util/qemu-option.c b/util/qemu-option.c
index de42e2a406..ef60af70fc 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -280,7 +280,7 @@ QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
 {
     QemuOpt *opt;
 
-    QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
+    QTAILQ_FOREACH_REVERSE(opt, &opts->head, next) {
         if (strcmp(opt->name, name) != 0)
             continue;
         return opt;
@@ -379,7 +379,7 @@ bool qemu_opt_has_help_opt(QemuOpts *opts)
 {
     QemuOpt *opt;
 
-    QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
+    QTAILQ_FOREACH_REVERSE(opt, &opts->head, next) {
         if (is_help_option(opt->name)) {
             return true;
         }
-- 
2.19.2

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

* [Qemu-devel] [PATCH 6/6] checkpatch: warn about queue/queue.h head structs that are not typedef-ed
  2018-12-06 23:23 [Qemu-devel] [PATCH for-4.0 0/6] qemu/queue.h usage cleanup, improved QTAILQ API Paolo Bonzini
                   ` (4 preceding siblings ...)
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 5/6] qemu/queue.h: simplify reverse access to QTAILQ Paolo Bonzini
@ 2018-12-06 23:23 ` Paolo Bonzini
  2018-12-07  9:02   ` Markus Armbruster
  5 siblings, 1 reply; 16+ messages in thread
From: Paolo Bonzini @ 2018-12-06 23:23 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 scripts/checkpatch.pl | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index a8d6e44107..b4b3495044 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2263,6 +2263,11 @@ sub process {
 			}
 		}
 
+		if ($line =~ /^.\s*(Q(?:S?LIST|SIMPLEQ|TAILQ)_HEAD)\s*\(\s*[^,]/ &&
+		    $line !~ /^.typedef/) {
+		    ERROR("named $1 should be typedefed separately\n" . $herecurr);
+		}
+
 # Need a space before open parenthesis after if, while etc
 		if ($line=~/\b(if|while|for|switch)\(/) {
 			ERROR("space required before the open parenthesis '('\n" . $herecurr);
-- 
2.19.2

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

* Re: [Qemu-devel] [PATCH 1/6] qemu/queue.h: do not access tqe_prev directly
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 1/6] qemu/queue.h: do not access tqe_prev directly Paolo Bonzini
@ 2018-12-07  7:14   ` Markus Armbruster
  2018-12-07 10:14   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 16+ messages in thread
From: Markus Armbruster @ 2018-12-07  7:14 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

Paolo Bonzini <pbonzini@redhat.com> writes:

> Use the QTAILQ_IN_USE macro instead, it does the same thing but the next
> patch will change it to a different definition.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  blockdev.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/blockdev.c b/blockdev.c
> index 81f95d920b..7604b2183b 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -4259,7 +4259,7 @@ void qmp_blockdev_del(const char *node_name, Error **errp)
>          goto out;
>      }
>  
> -    if (!bs->monitor_list.tqe_prev) {
> +    if (!QTAILQ_IN_USE(bs, monitor_list)) {
>          error_setg(errp, "Node %s is not owned by the monitor",
>                     bs->node_name);
>          goto out;

Reviewed-by: Markus Armbruster <armbru@redhat.com>

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

* Re: [Qemu-devel] [PATCH 2/6] qemu/queue.h: leave head structs anonymous unless necessary
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 2/6] qemu/queue.h: leave head structs anonymous unless necessary Paolo Bonzini
@ 2018-12-07  7:28   ` Markus Armbruster
  2018-12-07 13:47     ` Paolo Bonzini
  0 siblings, 1 reply; 16+ messages in thread
From: Markus Armbruster @ 2018-12-07  7:28 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

Paolo Bonzini <pbonzini@redhat.com> writes:

> Most list head structs need not be given a name.  In most cases the
> name is given just in case one is going to use QTAILQ_LAST, QTAILQ_PREV
> or reverse iteration, but this does not apply to lists of other kinds,
> and even for QTAILQ in practice this is only rarely needed.  In addition,
> we will soon reimplement those macros completely so that they do not
> need a name for the head struct.  So clean up everything, not giving a
> name except in the rare case where it is necessary.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
[...]
> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> index 4880a05399..4e1de942ce 100644
> --- a/accel/kvm/kvm-all.c
> +++ b/accel/kvm/kvm-all.c
> @@ -86,7 +86,7 @@ struct KVMState
>      int robust_singlestep;
>      int debugregs;
>  #ifdef KVM_CAP_SET_GUEST_DEBUG
> -    struct kvm_sw_breakpoint_head kvm_sw_breakpoints;
> +    QTAILQ_HEAD(, kvm_sw_breakpoint) kvm_sw_breakpoints;
>  #endif
>      int many_ioeventfds;
>      int intx_set_mask;
> @@ -102,7 +102,7 @@ struct KVMState
>      int nr_allocated_irq_routes;
>      unsigned long *used_gsi_bitmap;
>      unsigned int gsi_count;
> -    QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE];
> +    QTAILQ_HEAD(, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE];
>  #endif
>      KVMMemoryListener memory_listener;
>      QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus;
> diff --git a/block/gluster.c b/block/gluster.c
> index 5e300c96c8..72891060e3 100644
> --- a/block/gluster.c
> +++ b/block/gluster.c
> @@ -72,7 +72,7 @@ typedef struct ListElement {
>      GlfsPreopened saved;
>  } ListElement;
>  
> -static QLIST_HEAD(glfs_list, ListElement) glfs_list;
> +static QLIST_HEAD(, ListElement) glfs_list;
>  
>  static QemuOptsList qemu_gluster_create_opts = {
>      .name = "qemu-gluster-create-opts",
> diff --git a/block/mirror.c b/block/mirror.c
> index 8f52c6215d..6250cc3c87 100644
> --- a/block/mirror.c
> +++ b/block/mirror.c
> @@ -72,7 +72,7 @@ typedef struct MirrorBlockJob {
>      unsigned long *in_flight_bitmap;
>      int in_flight;
>      int64_t bytes_in_flight;
> -    QTAILQ_HEAD(MirrorOpList, MirrorOp) ops_in_flight;
> +    QTAILQ_HEAD(, MirrorOp) ops_in_flight;
>      int ret;
>      bool unmap;
>      int target_cluster_size;
> diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
> index accebef4cf..b946301429 100644
> --- a/block/qcow2-bitmap.c
> +++ b/block/qcow2-bitmap.c
> @@ -77,8 +77,6 @@ typedef struct Qcow2BitmapTable {
>      uint32_t size; /* number of 64bit entries */
>      QSIMPLEQ_ENTRY(Qcow2BitmapTable) entry;
>  } Qcow2BitmapTable;
> -typedef QSIMPLEQ_HEAD(Qcow2BitmapTableList, Qcow2BitmapTable)
> -    Qcow2BitmapTableList;
>  
>  typedef struct Qcow2Bitmap {
>      Qcow2BitmapTable table;
> @@ -1316,7 +1314,7 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp)
>      int ret;
>      Qcow2BitmapList *bm_list;
>      Qcow2Bitmap *bm;
> -    Qcow2BitmapTableList drop_tables;
> +    QSIMPLEQ_HEAD(, Qcow2BitmapTable) drop_tables;
>      Qcow2BitmapTable *tb, *tb_next;
>  
>      if (!bdrv_has_changed_persistent_bitmaps(bs)) {

Thanks for getting rid of typedefs like this one.

> diff --git a/block/qcow2.h b/block/qcow2.h
> index 8662b68575..d747dd14a2 100644
> --- a/block/qcow2.h
> +++ b/block/qcow2.h
> @@ -281,7 +281,7 @@ typedef struct BDRVQcow2State {
>      uint8_t *cluster_cache;
>      uint8_t *cluster_data;
>      uint64_t cluster_cache_offset;
> -    QLIST_HEAD(QCowClusterAlloc, QCowL2Meta) cluster_allocs;
> +    QLIST_HEAD(, QCowL2Meta) cluster_allocs;
>  
>      uint64_t *refcount_table;
>      uint64_t refcount_table_offset;
[Snip...]

Did you create this patch manually, or (partly) mechanically?

Commit message claims a named struct is not needed for "lists of other
kinds, and even for QTAILQ in practice this is only rarely needed".
Let's see:

    $ git-grep 'Q[A-Z]*_HEAD(,' | wc -l
    246
    $ git-grep 'Q[A-Z]*_HEAD([^,]' | grep -v '#define' | wc -l
    25

Yup, "rarely" is fair.

    $ git-grep 'Q[A-Z]*_HEAD([^,]' | grep -v '#define' | grep -v QTAILQ_HEAD
    block/qcow2-bitmap.c:typedef QSIMPLEQ_HEAD(Qcow2BitmapList, Qcow2Bitmap) Qcow2BitmapList;
    include/block/block.h:typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
    include/hw/vfio/vfio-common.h:typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList;
    qemu-bridge-helper.c:typedef QSIMPLEQ_HEAD(ACLList, ACLRule) ACLList;

Are these four names left in intentionally?

If the name is indeed not needed for lists of other kinds, should we
simplify the macros so their users don't have to supply an empty first
argument?

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

* Re: [Qemu-devel] [PATCH 3/6] qemu/queue.h: typedef QTAILQ heads
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 3/6] qemu/queue.h: typedef QTAILQ heads Paolo Bonzini
@ 2018-12-07  7:30   ` Markus Armbruster
  2018-12-07 10:15   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 16+ messages in thread
From: Markus Armbruster @ 2018-12-07  7:30 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

Paolo Bonzini <pbonzini@redhat.com> writes:

> This will be needed when we change the QTAILQ head and elem structs
> to unions.  However, it is also consistent with the usage elsewhere
> in QEMU for other list head structs (see for example FsMountList).
>
> Note that most QTAILQs only need their name in order to do backwards
> walks.  Those do not break with the struct->union change, and anyway
> the change will also remove the need to name heads when doing backwards
> walks, so those are not touched here.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Reviewed-by: Markus Armbruster <armbru@redhat.com>

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

* Re: [Qemu-devel] [PATCH 6/6] checkpatch: warn about queue/queue.h head structs that are not typedef-ed
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 6/6] checkpatch: warn about queue/queue.h head structs that are not typedef-ed Paolo Bonzini
@ 2018-12-07  9:02   ` Markus Armbruster
  2018-12-07 13:49     ` Paolo Bonzini
  0 siblings, 1 reply; 16+ messages in thread
From: Markus Armbruster @ 2018-12-07  9:02 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

Let's state the rationale for requiring a typedef in the commit
message, or point to a prior commit that has it.

Paolo Bonzini <pbonzini@redhat.com> writes:

> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  scripts/checkpatch.pl | 5 +++++
>  1 file changed, 5 insertions(+)
>
> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
> index a8d6e44107..b4b3495044 100755
> --- a/scripts/checkpatch.pl
> +++ b/scripts/checkpatch.pl
> @@ -2263,6 +2263,11 @@ sub process {
>  			}
>  		}
>  
> +		if ($line =~ /^.\s*(Q(?:S?LIST|SIMPLEQ|TAILQ)_HEAD)\s*\(\s*[^,]/ &&
> +		    $line !~ /^.typedef/) {
> +		    ERROR("named $1 should be typedefed separately\n" . $herecurr);
> +		}
> +
>  # Need a space before open parenthesis after if, while etc
>  		if ($line=~/\b(if|while|for|switch)\(/) {
>  			ERROR("space required before the open parenthesis '('\n" . $herecurr);

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

* Re: [Qemu-devel] [PATCH 4/6] qemu/queue.h: reimplement QTAILQ without pointer-to-pointers
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 4/6] qemu/queue.h: reimplement QTAILQ without pointer-to-pointers Paolo Bonzini
@ 2018-12-07  9:22   ` Markus Armbruster
  0 siblings, 0 replies; 16+ messages in thread
From: Markus Armbruster @ 2018-12-07  9:22 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

Paolo Bonzini <pbonzini@redhat.com> writes:

> QTAILQ is a doubly linked list, with a pointer-to-pointer to the last
> element from the head, and the previous element from each node.
>
> But if you squint enough, QTAILQ becomes a combination of a singly-linked
> forwards list, and another singly-linked list which goes backwards and
> is circular.  This is the idea that lets QTAILQ implement reverse
> iteration: only, because the backwards list points inside the node,
> accessing the previous element needs to go two steps back and one
> forwards.
>
> What this patch does is implement it in these terms, without actually
> changing the in-memory layout at all.  The coexistence of the two lists
> is realized by making QTAILQ_HEAD and QTAILQ_ENTRY unions of the forwards
> pointer and a generic QTailQLink node.  Thq QTailQLink can walk the list in

s/Thq/The/

> both directions; the union is needed so that the forwards pointer can
> have the correct type, as a sort of poor man's template.  While there
> are other ways to get the same layout without a union, this one has
> the advantage of simpler operation in the debugger, because the fields
> tqh_first and tqe_next still exist as before the patch.  Those fields are
> also used by scripts/qemugdb/mtree.py, so it's a good idea to preserve them.
>
> The advantage of the new representation is that the two-back-one-forward
> dance done by backwards accesses can be done all while operating on
> QTailQLinks.  No casting to the head struct is needed anymore because,
> even though the QTailQLink's forward pointer is a void *, we can use
> typeof to recover the correct type.  This patch only changes the
> implementation, not the interface.  The next patch will remove the head
> struct name from the backwards visit macros.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  include/qemu/queue.h       | 143 ++++++++++++++++---------------------
>  include/qemu/rcu_queue.h   |  45 ++++++------
>  scripts/cocci-macro-file.h |  24 ++-----
>  3 files changed, 93 insertions(+), 119 deletions(-)
>
> diff --git a/include/qemu/queue.h b/include/qemu/queue.h
> index ac418efc43..cb1bd6327c 100644
> --- a/include/qemu/queue.h
> +++ b/include/qemu/queue.h
> @@ -346,77 +346,80 @@ struct {                                                                \
>  #define QSIMPLEQ_FIRST(head)        ((head)->sqh_first)
>  #define QSIMPLEQ_NEXT(elm, field)   ((elm)->field.sqe_next)
>  
> +typedef struct QTailQLink {
> +    void *tql_next;
> +    struct QTailQLink *tql_prev;
> +} QTailQLink;
>  
>  /*
> - * Tail queue definitions.
> + * Tail queue definitions.  The union acts as a poor man template, as if
> + * it were QTailQLink<type>.
>   */
> -#define Q_TAILQ_HEAD(name, type, qual)                                  \
> -struct name {                                                           \
> -        qual type *tqh_first;           /* first element */             \
> -        qual type *qual *tqh_last;      /* addr of last next element */ \
> +#define QTAILQ_HEAD(name, type)                                         \
> +union name {                                                            \
> +        struct type *tqh_first;       /* first element */               \
> +        QTailQLink tqh_circ;          /* link for circular backwards list */ \
>  }
> -#define QTAILQ_HEAD(name, type)  Q_TAILQ_HEAD(name, struct type,)
>  
>  #define QTAILQ_HEAD_INITIALIZER(head)                                   \
> -        { NULL, &(head).tqh_first }
> +        { .tqh_circ = { NULL, &(head).tqh_circ } }
>  
> -#define Q_TAILQ_ENTRY(type, qual)                                       \
> -struct {                                                                \
> -        qual type *tqe_next;            /* next element */              \
> -        qual type *qual *tqe_prev;      /* address of previous next element */\
> +#define QTAILQ_ENTRY(type)                                              \
> +union {                                                                 \
> +        struct type *tqe_next;        /* next element */                \
> +        QTailQLink tqe_circ;          /* link for circular backwards list */ \
>  }
> -#define QTAILQ_ENTRY(type)       Q_TAILQ_ENTRY(struct type,)

I think this conflates two things:

(a) The one advertized by the commit message, and

(b) Getting rid of Q_TAILQ_HEAD(), Q_TAILQ_ENTRY() as unnecessary
complications.

I suspect doing (b) first in a separate patch would make (a) a bit
easier to review.

The way my brain works, I need to redo your explanation my own way;
reading your (undoubtedly fine) commit message won't do.

Let me start with examining (a) in the light of "no change of the
in-memory layout".

The head is a pair of pointers.  Before the patch, they are

    struct T *tqh_first;
    struct T **tqh_last;

The patch changes tqh_first from the first member of a struct into the
first member of a union, which is effectively the same.  Okay.

It adds tqh_circ.tql_next as alias of type void *.  Exploits uniform
pointer representation on sane machines.  Okay.

It replaces tqh_last by tqh_circ.tql_prev, changing its type from struct
T ** to QTailQLink *.  

The entry has the same structure, only the names are different.

tqe_next stays the same, with new alias tqe_circ.tql_next.

tqe_prev gets replaced by tqe_circ.tql_prev.

The commit message claims the QTailQLink permits walking the list in
both directions.  True: ->tqe_next->FIELD.tqe_circ is the next
QTailQLink, and ->tql_prev points to the previous one.

To go from QTailQLink to the T that contains it, we can
->tql_prev->tql->next (the backward list is circular).  This yields a
void *, which we need to cast to struct T *.

The cast to struct T * can be done without having to name struct T when
we have a head or an entry: typeof ->tqh_first or ->tqe_next does the
trick.

Yup, that should work.  I figure the changes below are actually almost
mechanical.

Or did I screw up somewhere?

>  
>  /*
>   * Tail queue functions.
>   */
>  #define QTAILQ_INIT(head) do {                                          \
>          (head)->tqh_first = NULL;                                       \
> -        (head)->tqh_last = &(head)->tqh_first;                          \
> +        (head)->tqh_circ.tql_prev = &(head)->tqh_circ;                  \
>  } while (/*CONSTCOND*/0)
>  
>  #define QTAILQ_INSERT_HEAD(head, elm, field) do {                       \
>          if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)        \
> -                (head)->tqh_first->field.tqe_prev =                     \
> -                    &(elm)->field.tqe_next;                             \
> +            (head)->tqh_first->field.tqe_circ.tql_prev =                \
> +                &(elm)->field.tqe_circ;                                 \
>          else                                                            \
> -                (head)->tqh_last = &(elm)->field.tqe_next;              \
> +            (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;         \
>          (head)->tqh_first = (elm);                                      \
> -        (elm)->field.tqe_prev = &(head)->tqh_first;                     \
> +        (elm)->field.tqe_circ.tql_prev = &(head)->tqh_circ;             \
>  } while (/*CONSTCOND*/0)
>  
>  #define QTAILQ_INSERT_TAIL(head, elm, field) do {                       \
>          (elm)->field.tqe_next = NULL;                                   \
> -        (elm)->field.tqe_prev = (head)->tqh_last;                       \
> -        *(head)->tqh_last = (elm);                                      \
> -        (head)->tqh_last = &(elm)->field.tqe_next;                      \
> +        (elm)->field.tqe_circ.tql_prev = (head)->tqh_circ.tql_prev;     \
> +        (head)->tqh_circ.tql_prev->tql_next = (elm);                    \
> +        (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;             \
>  } while (/*CONSTCOND*/0)
>  
>  #define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do {             \
>          if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
> -                (elm)->field.tqe_next->field.tqe_prev =                 \
> -                    &(elm)->field.tqe_next;                             \
> +            (elm)->field.tqe_next->field.tqe_circ.tql_prev =            \
> +                &(elm)->field.tqe_circ;                                 \
>          else                                                            \
> -                (head)->tqh_last = &(elm)->field.tqe_next;              \
> +            (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;         \
>          (listelm)->field.tqe_next = (elm);                              \
> -        (elm)->field.tqe_prev = &(listelm)->field.tqe_next;             \
> +        (elm)->field.tqe_circ.tql_prev = &(listelm)->field.tqe_circ;    \
>  } while (/*CONSTCOND*/0)
>  
> -#define QTAILQ_INSERT_BEFORE(listelm, elm, field) do {                  \
> -        (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
> -        (elm)->field.tqe_next = (listelm);                              \
> -        *(listelm)->field.tqe_prev = (elm);                             \
> -        (listelm)->field.tqe_prev = &(elm)->field.tqe_next;             \
> +#define QTAILQ_INSERT_BEFORE(listelm, elm, field) do {                       \
> +        (elm)->field.tqe_circ.tql_prev = (listelm)->field.tqe_circ.tql_prev; \
> +        (elm)->field.tqe_next = (listelm);                                   \
> +        (listelm)->field.tqe_circ.tql_prev->tql_next = (elm);                \
> +        (listelm)->field.tqe_circ.tql_prev = &(elm)->field.tqe_circ;         \
>  } while (/*CONSTCOND*/0)
>  
>  #define QTAILQ_REMOVE(head, elm, field) do {                            \
>          if (((elm)->field.tqe_next) != NULL)                            \
> -                (elm)->field.tqe_next->field.tqe_prev =                 \
> -                    (elm)->field.tqe_prev;                              \
> +            (elm)->field.tqe_next->field.tqe_circ.tql_prev =            \
> +                (elm)->field.tqe_circ.tql_prev;                         \
>          else                                                            \
> -                (head)->tqh_last = (elm)->field.tqe_prev;               \
> -        *(elm)->field.tqe_prev = (elm)->field.tqe_next;                 \
> -        (elm)->field.tqe_prev = NULL;                                   \
> +            (head)->tqh_circ.tql_prev = (elm)->field.tqe_circ.tql_prev; \
> +        (elm)->field.tqe_circ.tql_prev->tql_next = (elm)->field.tqe_next; \
> +        (elm)->field.tqe_circ.tql_prev = NULL;                          \
>  } while (/*CONSTCOND*/0)
>  
>  #define QTAILQ_FOREACH(var, head, field)                                \
> @@ -430,13 +433,13 @@ struct {                                                                \
>                  (var) = (next_var))
>  
>  #define QTAILQ_FOREACH_REVERSE(var, head, headname, field)              \
> -        for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));    \
> +        for ((var) = QTAILQ_LAST(head, headname);                       \
>                  (var);                                                  \
> -                (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
> +                (var) = QTAILQ_PREV(var, headname, field))
>  
>  #define QTAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, prev_var) \
> -        for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
> -             (var) && ((prev_var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)), 1); \
> +        for ((var) = QTAILQ_LAST(head, headname);                       \
> +             (var) && ((prev_var) = QTAILQ_PREV(var, headname, field)); \
>               (var) = (prev_var))
>  
>  /*
> @@ -445,71 +448,49 @@ struct {                                                                \
>  #define QTAILQ_EMPTY(head)               ((head)->tqh_first == NULL)
>  #define QTAILQ_FIRST(head)               ((head)->tqh_first)
>  #define QTAILQ_NEXT(elm, field)          ((elm)->field.tqe_next)
> -#define QTAILQ_IN_USE(elm, field)        ((elm)->field.tqe_prev != NULL)
> +#define QTAILQ_IN_USE(elm, field)        ((elm)->field.tqe_circ.tql_prev != NULL)
>  
> +#define QTAILQ_LINK_PREV(link)                                          \
> +        ((link).tql_prev->tql_prev->tql_next)
>  #define QTAILQ_LAST(head, headname) \
> -        (*(((struct headname *)((head)->tqh_last))->tqh_last))
> +        ((typeof((head)->tqh_first)) QTAILQ_LINK_PREV((head)->tqh_circ))
>  #define QTAILQ_PREV(elm, headname, field) \
> -        (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
> +        ((typeof((elm)->field.tqe_next)) QTAILQ_LINK_PREV((elm)->field.tqe_circ))
>  
>  #define field_at_offset(base, offset, type)                                    \
> -        ((type) (((char *) (base)) + (offset)))
> -
> -typedef struct DUMMY_Q_ENTRY DUMMY_Q_ENTRY;
> -typedef struct DUMMY_Q DUMMY_Q;
> -
> -struct DUMMY_Q_ENTRY {
> -        QTAILQ_ENTRY(DUMMY_Q_ENTRY) next;
> -};
> -
> -struct DUMMY_Q {
> -        QTAILQ_HEAD(DUMMY_Q_HEAD, DUMMY_Q_ENTRY) head;
> -};
> -
> -#define dummy_q ((DUMMY_Q *) 0)
> -#define dummy_qe ((DUMMY_Q_ENTRY *) 0)
> +        ((type *) (((char *) (base)) + (offset)))
>  
>  /*
> - * Offsets of layout of a tail queue head.
> - */
> -#define QTAILQ_FIRST_OFFSET (offsetof(typeof(dummy_q->head), tqh_first))
> -#define QTAILQ_LAST_OFFSET  (offsetof(typeof(dummy_q->head), tqh_last))
> -/*
> - * Raw access of elements of a tail queue
> + * Raw access of elements of a tail queue head.  Offsets are all zero
> + * because it's a union.
>   */
>  #define QTAILQ_RAW_FIRST(head)                                                 \
> -        (*field_at_offset(head, QTAILQ_FIRST_OFFSET, void **))
> -#define QTAILQ_RAW_TQH_LAST(head)                                              \
> -        (*field_at_offset(head, QTAILQ_LAST_OFFSET, void ***))
> -
> -/*
> - * Offsets of layout of a tail queue element.
> - */
> -#define QTAILQ_NEXT_OFFSET (offsetof(typeof(dummy_qe->next), tqe_next))
> -#define QTAILQ_PREV_OFFSET (offsetof(typeof(dummy_qe->next), tqe_prev))
> +        field_at_offset(head, 0, void *)
> +#define QTAILQ_RAW_TQH_CIRC(head)                                              \
> +        field_at_offset(head, 0, QTailQLink)
>  
>  /*
>   * Raw access of elements of a tail entry
>   */
>  #define QTAILQ_RAW_NEXT(elm, entry)                                            \
> -        (*field_at_offset(elm, entry + QTAILQ_NEXT_OFFSET, void **))
> -#define QTAILQ_RAW_TQE_PREV(elm, entry)                                        \
> -        (*field_at_offset(elm, entry + QTAILQ_PREV_OFFSET, void ***))
> +        field_at_offset(elm, entry, void *)
> +#define QTAILQ_RAW_TQE_CIRC(elm, entry)                                        \
> +        field_at_offset(elm, entry, QTailQLink)
>  /*
> - * Tail queue tranversal using pointer arithmetic.
> + * Tail queue traversal using pointer arithmetic.
>   */
>  #define QTAILQ_RAW_FOREACH(elm, head, entry)                                   \
> -        for ((elm) = QTAILQ_RAW_FIRST(head);                                   \
> +        for ((elm) = *QTAILQ_RAW_FIRST(head);                                  \
>               (elm);                                                            \
> -             (elm) = QTAILQ_RAW_NEXT(elm, entry))
> +             (elm) = *QTAILQ_RAW_NEXT(elm, entry))
>  /*
>   * Tail queue insertion using pointer arithmetic.
>   */
> -#define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) do {                          \
> -        QTAILQ_RAW_NEXT(elm, entry) = NULL;                                    \
> -        QTAILQ_RAW_TQE_PREV(elm, entry) = QTAILQ_RAW_TQH_LAST(head);           \
> -        *QTAILQ_RAW_TQH_LAST(head) = (elm);                                    \
> -        QTAILQ_RAW_TQH_LAST(head) = &QTAILQ_RAW_NEXT(elm, entry);              \
> +#define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) do {                           \
> +        *QTAILQ_RAW_NEXT(elm, entry) = NULL;                                    \
> +        QTAILQ_RAW_TQE_CIRC(elm, entry)->tql_prev = QTAILQ_RAW_TQH_CIRC(head)->tql_prev; \
> +        QTAILQ_RAW_TQH_CIRC(head)->tql_prev->tql_next = (elm);                  \
> +        QTAILQ_RAW_TQH_CIRC(head)->tql_prev = QTAILQ_RAW_TQE_CIRC(elm, entry);  \
>  } while (/*CONSTCOND*/0)
>  
>  #endif /* QEMU_SYS_QUEUE_H */
> diff --git a/include/qemu/rcu_queue.h b/include/qemu/rcu_queue.h
> index 904b3372dc..2bee5dff80 100644
> --- a/include/qemu/rcu_queue.h
> +++ b/include/qemu/rcu_queue.h
> @@ -206,47 +206,50 @@ extern "C" {
>  #define QTAILQ_INSERT_HEAD_RCU(head, elm, field) do {                   \
>      (elm)->field.tqe_next = (head)->tqh_first;                          \
>      if ((elm)->field.tqe_next != NULL) {                                \
> -        (head)->tqh_first->field.tqe_prev = &(elm)->field.tqe_next;     \
> +        (head)->tqh_first->field.tqe_circ.tql_prev =                    \
> +            &(elm)->field.tqe_circ;                                     \
>      } else {                                                            \
> -        (head)->tqh_last = &(elm)->field.tqe_next;                      \
> +        (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;             \
>      }                                                                   \
>      atomic_rcu_set(&(head)->tqh_first, (elm));                          \
> -    (elm)->field.tqe_prev = &(head)->tqh_first;                         \
> +    (elm)->field.tqe_circ.tql_prev = &(head)->tqh_circ;                 \
>  } while (/*CONSTCOND*/0)
>  
> -#define QTAILQ_INSERT_TAIL_RCU(head, elm, field) do {               \
> -    (elm)->field.tqe_next = NULL;                                   \
> -    (elm)->field.tqe_prev = (head)->tqh_last;                       \
> -    atomic_rcu_set((head)->tqh_last, (elm));                        \
> -    (head)->tqh_last = &(elm)->field.tqe_next;                      \
> +#define QTAILQ_INSERT_TAIL_RCU(head, elm, field) do {                   \
> +    (elm)->field.tqe_next = NULL;                                       \
> +    (elm)->field.tqe_circ.tql_prev = (head)->tqh_circ.tql_prev;         \
> +    atomic_rcu_set(&(head)->tqh_circ.tql_prev->tql_next, (elm));        \
> +    (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;                 \
>  } while (/*CONSTCOND*/0)
>  
>  #define QTAILQ_INSERT_AFTER_RCU(head, listelm, elm, field) do {         \
>      (elm)->field.tqe_next = (listelm)->field.tqe_next;                  \
>      if ((elm)->field.tqe_next != NULL) {                                \
> -        (elm)->field.tqe_next->field.tqe_prev = &(elm)->field.tqe_next; \
> +        (elm)->field.tqe_next->field.tqe_circ.tql_prev =                \
> +            &(elm)->field.tqe_circ;                                     \
>      } else {                                                            \
> -        (head)->tqh_last = &(elm)->field.tqe_next;                      \
> +        (head)->tqh_circ.tql_prev = &(elm)->field.tqe_circ;             \
>      }                                                                   \
>      atomic_rcu_set(&(listelm)->field.tqe_next, (elm));                  \
> -    (elm)->field.tqe_prev = &(listelm)->field.tqe_next;                 \
> +    (elm)->field.tqe_circ.tql_prev = &(listelm)->field.tqe_circ;        \
>  } while (/*CONSTCOND*/0)
>  
> -#define QTAILQ_INSERT_BEFORE_RCU(listelm, elm, field) do {          \
> -    (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
> -    (elm)->field.tqe_next = (listelm);                              \
> -    atomic_rcu_set((listelm)->field.tqe_prev, (elm));               \
> -    (listelm)->field.tqe_prev = &(elm)->field.tqe_next;             \
> -    } while (/*CONSTCOND*/0)
> +#define QTAILQ_INSERT_BEFORE_RCU(listelm, elm, field) do {                \
> +    (elm)->field.tqe_circ.tql_prev = (listelm)->field.tqe_circ.tql_prev;  \
> +    (elm)->field.tqe_next = (listelm);                                    \
> +    atomic_rcu_set(&(listelm)->field.tqe_circ.tql_prev->tql_next, (elm)); \
> +    (listelm)->field.tqe_circ.tql_prev = &(elm)->field.tqe_circ;          \
> +} while (/*CONSTCOND*/0)
>  
>  #define QTAILQ_REMOVE_RCU(head, elm, field) do {                        \
>      if (((elm)->field.tqe_next) != NULL) {                              \
> -        (elm)->field.tqe_next->field.tqe_prev = (elm)->field.tqe_prev;  \
> +        (elm)->field.tqe_next->field.tqe_circ.tql_prev =                \
> +            (elm)->field.tqe_circ.tql_prev;                             \
>      } else {                                                            \
> -        (head)->tqh_last = (elm)->field.tqe_prev;                       \
> +        (head)->tqh_circ.tql_prev = (elm)->field.tqe_circ.tql_prev;     \
>      }                                                                   \
> -    atomic_set((elm)->field.tqe_prev, (elm)->field.tqe_next);           \
> -    (elm)->field.tqe_prev = NULL;                                       \
> +    atomic_set(&(elm)->field.tqe_circ.tql_prev->tql_next, (elm)->field.tqe_next); \
> +    (elm)->field.tqe_circ.tql_prev = NULL;                              \
>  } while (/*CONSTCOND*/0)
>  
>  #define QTAILQ_FOREACH_RCU(var, head, field)                            \
> diff --git a/scripts/cocci-macro-file.h b/scripts/cocci-macro-file.h
> index 9f2e72e7e1..7f1006e97c 100644
> --- a/scripts/cocci-macro-file.h
> +++ b/scripts/cocci-macro-file.h
> @@ -93,29 +93,19 @@ struct {                                                                \
>  /*
>   * Tail queue definitions.
>   */
> -#define Q_TAILQ_HEAD(name, type, qual)                                  \
> -struct name {                                                           \
> -        qual type *tqh_first;           /* first element */             \
> -        qual type *qual *tqh_last;      /* addr of last next element */ \
> -}
>  #define QTAILQ_HEAD(name, type)                                         \
> -struct name {                                                           \
> -        type *tqh_first;      /* first element */                       \
> -        type **tqh_last;      /* addr of last next element */           \
> +union name {                                                            \
> +        struct type *tqh_first;       /* first element */               \
> +        QTailQLink tqh_circ;          /* link for last element */       \
>  }
>  
>  #define QTAILQ_HEAD_INITIALIZER(head)                                   \
> -        { NULL, &(head).tqh_first }
> +        { .tqh_circ = { NULL, &(head).tqh_circ } }
>  
> -#define Q_TAILQ_ENTRY(type, qual)                                       \
> -struct {                                                                \
> -        qual type *tqe_next;            /* next element */              \
> -        qual type *qual *tqe_prev;      /* address of previous next element */\
> -}
>  #define QTAILQ_ENTRY(type)                                              \
> -struct {                                                                \
> -        type *tqe_next;       /* next element */                        \
> -        type **tqe_prev;      /* address of previous next element */    \
> +union {                                                                 \
> +        struct type *tqe_next;        /* next element */                \
> +        QTailQLink tqe_circ;          /* link for prev element */       \
>  }
>  
>  /* From glib */

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

* Re: [Qemu-devel] [PATCH 1/6] qemu/queue.h: do not access tqe_prev directly
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 1/6] qemu/queue.h: do not access tqe_prev directly Paolo Bonzini
  2018-12-07  7:14   ` Markus Armbruster
@ 2018-12-07 10:14   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 16+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-12-07 10:14 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel

On 12/7/18 12:23 AM, Paolo Bonzini wrote:
> Use the QTAILQ_IN_USE macro instead, it does the same thing but the next
> patch will change it to a different definition.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

> ---
>  blockdev.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/blockdev.c b/blockdev.c
> index 81f95d920b..7604b2183b 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -4259,7 +4259,7 @@ void qmp_blockdev_del(const char *node_name, Error **errp)
>          goto out;
>      }
>  
> -    if (!bs->monitor_list.tqe_prev) {
> +    if (!QTAILQ_IN_USE(bs, monitor_list)) {
>          error_setg(errp, "Node %s is not owned by the monitor",
>                     bs->node_name);
>          goto out;
> 

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

* Re: [Qemu-devel] [PATCH 3/6] qemu/queue.h: typedef QTAILQ heads
  2018-12-06 23:23 ` [Qemu-devel] [PATCH 3/6] qemu/queue.h: typedef QTAILQ heads Paolo Bonzini
  2018-12-07  7:30   ` Markus Armbruster
@ 2018-12-07 10:15   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 16+ messages in thread
From: Philippe Mathieu-Daudé @ 2018-12-07 10:15 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel

On 12/7/18 12:23 AM, Paolo Bonzini wrote:
> This will be needed when we change the QTAILQ head and elem structs
> to unions.  However, it is also consistent with the usage elsewhere
> in QEMU for other list head structs (see for example FsMountList).
> 
> Note that most QTAILQs only need their name in order to do backwards
> walks.  Those do not break with the struct->union change, and anyway
> the change will also remove the need to name heads when doing backwards
> walks, so those are not touched here.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

> ---
>  exec.c            |  3 ++-
>  include/qom/cpu.h |  5 +++--
>  ui/input.c        | 14 ++++++++------
>  3 files changed, 13 insertions(+), 9 deletions(-)
> 
> diff --git a/exec.c b/exec.c
> index b6b2007f27..a629c98eb5 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -94,7 +94,8 @@ int target_page_bits;
>  bool target_page_bits_decided;
>  #endif
>  
> -struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
> +CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
> +
>  /* current CPU in the current thread. It is only valid inside
>     cpu_exec() */
>  __thread CPUState *current_cpu;
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 62aef77b87..4662a205c1 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -435,8 +435,9 @@ struct CPUState {
>      GArray *iommu_notifiers;
>  };
>  
> -QTAILQ_HEAD(CPUTailQ, CPUState);
> -extern struct CPUTailQ cpus;
> +typedef QTAILQ_HEAD(CPUTailQ, CPUState) CPUTailQ;
> +extern CPUTailQ cpus;
> +
>  #define first_cpu        QTAILQ_FIRST_RCU(&cpus)
>  #define CPU_NEXT(cpu)    QTAILQ_NEXT_RCU(cpu, node)
>  #define CPU_FOREACH(cpu) QTAILQ_FOREACH_RCU(cpu, &cpus, node)
> diff --git a/ui/input.c b/ui/input.c
> index 7c9a4109c4..35c7964f64 100644
> --- a/ui/input.c
> +++ b/ui/input.c
> @@ -19,6 +19,9 @@ struct QemuInputHandlerState {
>  };
>  
>  typedef struct QemuInputEventQueue QemuInputEventQueue;
> +typedef QTAILQ_HEAD(QemuInputEventQueueHead, QemuInputEventQueue)
> +    QemuInputEventQueueHead;
> +
>  struct QemuInputEventQueue {
>      enum {
>          QEMU_INPUT_QUEUE_DELAY = 1,
> @@ -37,8 +40,7 @@ static QTAILQ_HEAD(, QemuInputHandlerState) handlers =
>  static NotifierList mouse_mode_notifiers =
>      NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers);
>  
> -static QTAILQ_HEAD(QemuInputEventQueueHead, QemuInputEventQueue) kbd_queue =
> -    QTAILQ_HEAD_INITIALIZER(kbd_queue);
> +static QemuInputEventQueueHead kbd_queue = QTAILQ_HEAD_INITIALIZER(kbd_queue);
>  static QEMUTimer *kbd_timer;
>  static uint32_t kbd_default_delay_ms = 10;
>  static uint32_t queue_count;
> @@ -257,7 +259,7 @@ static void qemu_input_event_trace(QemuConsole *src, InputEvent *evt)
>  
>  static void qemu_input_queue_process(void *opaque)
>  {
> -    struct QemuInputEventQueueHead *queue = opaque;
> +    QemuInputEventQueueHead *queue = opaque;
>      QemuInputEventQueue *item;
>  
>      g_assert(!QTAILQ_EMPTY(queue));
> @@ -288,7 +290,7 @@ static void qemu_input_queue_process(void *opaque)
>      }
>  }
>  
> -static void qemu_input_queue_delay(struct QemuInputEventQueueHead *queue,
> +static void qemu_input_queue_delay(QemuInputEventQueueHead *queue,
>                                     QEMUTimer *timer, uint32_t delay_ms)
>  {
>      QemuInputEventQueue *item = g_new0(QemuInputEventQueue, 1);
> @@ -306,7 +308,7 @@ static void qemu_input_queue_delay(struct QemuInputEventQueueHead *queue,
>      }
>  }
>  
> -static void qemu_input_queue_event(struct QemuInputEventQueueHead *queue,
> +static void qemu_input_queue_event(QemuInputEventQueueHead *queue,
>                                     QemuConsole *src, InputEvent *evt)
>  {
>      QemuInputEventQueue *item = g_new0(QemuInputEventQueue, 1);
> @@ -318,7 +320,7 @@ static void qemu_input_queue_event(struct QemuInputEventQueueHead *queue,
>      queue_count++;
>  }
>  
> -static void qemu_input_queue_sync(struct QemuInputEventQueueHead *queue)
> +static void qemu_input_queue_sync(QemuInputEventQueueHead *queue)
>  {
>      QemuInputEventQueue *item = g_new0(QemuInputEventQueue, 1);
>  
> 

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

* Re: [Qemu-devel] [PATCH 2/6] qemu/queue.h: leave head structs anonymous unless necessary
  2018-12-07  7:28   ` Markus Armbruster
@ 2018-12-07 13:47     ` Paolo Bonzini
  0 siblings, 0 replies; 16+ messages in thread
From: Paolo Bonzini @ 2018-12-07 13:47 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel

On 07/12/18 08:28, Markus Armbruster wrote:
> 
>     $ git-grep 'Q[A-Z]*_HEAD([^,]' | grep -v '#define' | grep -v QTAILQ_HEAD
>     block/qcow2-bitmap.c:typedef QSIMPLEQ_HEAD(Qcow2BitmapList, Qcow2Bitmap) Qcow2BitmapList;
>     include/block/block.h:typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
>     include/hw/vfio/vfio-common.h:typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList;
>     qemu-bridge-helper.c:typedef QSIMPLEQ_HEAD(ACLList, ACLRule) ACLList;
> 
> Are these four names left in intentionally?

Yes, they are the ones which are used in extern global variables or in
function parameters.  If they are static variables or struct fields, on
the other hand, you don't need the typedef.

The same is also true of the handful of QTAILQ head structs that are
typedefed in 3/6.

I'll add this to the commit message.

> If the name is indeed not needed for lists of other kinds, should we
> simplify the macros so their users don't have to supply an empty first
> argument?

No, it's just a coincidence.  For example QTAILQ needs it (patch 3/6).

Paolo

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

* Re: [Qemu-devel] [PATCH 6/6] checkpatch: warn about queue/queue.h head structs that are not typedef-ed
  2018-12-07  9:02   ` Markus Armbruster
@ 2018-12-07 13:49     ` Paolo Bonzini
  0 siblings, 0 replies; 16+ messages in thread
From: Paolo Bonzini @ 2018-12-07 13:49 UTC (permalink / raw)
  To: Markus Armbruster; +Cc: qemu-devel

On 07/12/18 10:02, Markus Armbruster wrote:
> Let's state the rationale for requiring a typedef in the commit
> message, or point to a prior commit that has it.

Sure---the rationale is simply that they are structs (or unions in the
case of QTAILQ but it's just an implementation detail), and we use
typedef for structs.

Paolo

> Paolo Bonzini <pbonzini@redhat.com> writes:
> 
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>  scripts/checkpatch.pl | 5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
>> index a8d6e44107..b4b3495044 100755
>> --- a/scripts/checkpatch.pl
>> +++ b/scripts/checkpatch.pl
>> @@ -2263,6 +2263,11 @@ sub process {
>>  			}
>>  		}
>>  
>> +		if ($line =~ /^.\s*(Q(?:S?LIST|SIMPLEQ|TAILQ)_HEAD)\s*\(\s*[^,]/ &&
>> +		    $line !~ /^.typedef/) {
>> +		    ERROR("named $1 should be typedefed separately\n" . $herecurr);
>> +		}
>> +
>>  # Need a space before open parenthesis after if, while etc
>>  		if ($line=~/\b(if|while|for|switch)\(/) {
>>  			ERROR("space required before the open parenthesis '('\n" . $herecurr);

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

end of thread, other threads:[~2018-12-07 13:49 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-06 23:23 [Qemu-devel] [PATCH for-4.0 0/6] qemu/queue.h usage cleanup, improved QTAILQ API Paolo Bonzini
2018-12-06 23:23 ` [Qemu-devel] [PATCH 1/6] qemu/queue.h: do not access tqe_prev directly Paolo Bonzini
2018-12-07  7:14   ` Markus Armbruster
2018-12-07 10:14   ` Philippe Mathieu-Daudé
2018-12-06 23:23 ` [Qemu-devel] [PATCH 2/6] qemu/queue.h: leave head structs anonymous unless necessary Paolo Bonzini
2018-12-07  7:28   ` Markus Armbruster
2018-12-07 13:47     ` Paolo Bonzini
2018-12-06 23:23 ` [Qemu-devel] [PATCH 3/6] qemu/queue.h: typedef QTAILQ heads Paolo Bonzini
2018-12-07  7:30   ` Markus Armbruster
2018-12-07 10:15   ` Philippe Mathieu-Daudé
2018-12-06 23:23 ` [Qemu-devel] [PATCH 4/6] qemu/queue.h: reimplement QTAILQ without pointer-to-pointers Paolo Bonzini
2018-12-07  9:22   ` Markus Armbruster
2018-12-06 23:23 ` [Qemu-devel] [PATCH 5/6] qemu/queue.h: simplify reverse access to QTAILQ Paolo Bonzini
2018-12-06 23:23 ` [Qemu-devel] [PATCH 6/6] checkpatch: warn about queue/queue.h head structs that are not typedef-ed Paolo Bonzini
2018-12-07  9:02   ` Markus Armbruster
2018-12-07 13:49     ` 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.