diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/block/nbd.h | 11 | ||||
| -rw-r--r-- | include/exec/cpu-common.h | 2 | ||||
| -rw-r--r-- | include/exec/exec-all.h | 51 | ||||
| -rw-r--r-- | include/exec/memory-internal.h | 6 | ||||
| -rw-r--r-- | include/exec/tb-context.h | 4 | ||||
| -rw-r--r-- | include/qemu/qht.h | 32 |
6 files changed, 70 insertions, 36 deletions
diff --git a/include/block/nbd.h b/include/block/nbd.h index fcdcd54502..daaeae61bf 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -135,6 +135,7 @@ typedef struct NBDExtent { #define NBD_FLAG_SEND_TRIM (1 << 5) /* Send TRIM (discard) */ #define NBD_FLAG_SEND_WRITE_ZEROES (1 << 6) /* Send WRITE_ZEROES */ #define NBD_FLAG_SEND_DF (1 << 7) /* Send DF (Do not Fragment) */ +#define NBD_FLAG_SEND_CACHE (1 << 8) /* Send CACHE (prefetch) */ /* New-style handshake (global) flags, sent from server to client, and control what will happen during handshake phase. */ @@ -195,7 +196,7 @@ enum { NBD_CMD_DISC = 2, NBD_CMD_FLUSH = 3, NBD_CMD_TRIM = 4, - /* 5 reserved for failed experiment NBD_CMD_CACHE */ + NBD_CMD_CACHE = 5, NBD_CMD_WRITE_ZEROES = 6, NBD_CMD_BLOCK_STATUS = 7, }; @@ -229,11 +230,13 @@ enum { #define NBD_REPLY_TYPE_ERROR NBD_REPLY_ERR(1) #define NBD_REPLY_TYPE_ERROR_OFFSET NBD_REPLY_ERR(2) -/* Flags for extents (NBDExtent.flags) of NBD_REPLY_TYPE_BLOCK_STATUS, - * for base:allocation meta context */ +/* Extent flags for base:allocation in NBD_REPLY_TYPE_BLOCK_STATUS */ #define NBD_STATE_HOLE (1 << 0) #define NBD_STATE_ZERO (1 << 1) +/* Extent flags for qemu:dirty-bitmap in NBD_REPLY_TYPE_BLOCK_STATUS */ +#define NBD_STATE_DIRTY (1 << 0) + static inline bool nbd_reply_type_is_error(int type) { return type & (1 << 15); @@ -315,6 +318,8 @@ void nbd_client_put(NBDClient *client); void nbd_server_start(SocketAddress *addr, const char *tls_creds, Error **errp); +void nbd_export_bitmap(NBDExport *exp, const char *bitmap, + const char *bitmap_export_name, Error **errp); /* nbd_read * Reads @size bytes from @ioc. Returns 0 on success. diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index 0b58e262f3..18b40d6145 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -23,7 +23,7 @@ typedef struct CPUListState { FILE *file; } CPUListState; -/* The CPU list lock nests outside tb_lock/tb_unlock. */ +/* The CPU list lock nests outside page_(un)lock or mmap_(un)lock */ void qemu_init_cpu_list(void); void cpu_list_lock(void); void cpu_list_unlock(void); diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 8bbea787a9..25a6f28ab8 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -345,7 +345,7 @@ struct TranslationBlock { #define CF_LAST_IO 0x00008000 /* Last insn may be an IO access. */ #define CF_NOCACHE 0x00010000 /* To be freed after execution */ #define CF_USE_ICOUNT 0x00020000 -#define CF_INVALID 0x00040000 /* TB is stale. Setters need tb_lock */ +#define CF_INVALID 0x00040000 /* TB is stale. Set with @jmp_lock held */ #define CF_PARALLEL 0x00080000 /* Generate code for a parallel context */ /* cflags' mask for hashing/comparison */ #define CF_HASH_MASK \ @@ -359,10 +359,14 @@ struct TranslationBlock { /* original tb when cflags has CF_NOCACHE */ struct TranslationBlock *orig_tb; /* first and second physical page containing code. The lower bit - of the pointer tells the index in page_next[] */ - struct TranslationBlock *page_next[2]; + of the pointer tells the index in page_next[]. + The list is protected by the TB's page('s) lock(s) */ + uintptr_t page_next[2]; tb_page_addr_t page_addr[2]; + /* jmp_lock placed here to fill a 4-byte hole. Its documentation is below */ + QemuSpin jmp_lock; + /* The following data are used to directly call another TB from * the code of this one. This can be done either by emitting direct or * indirect native jump instructions. These jumps are reset so that the TB @@ -374,20 +378,26 @@ struct TranslationBlock { #define TB_JMP_RESET_OFFSET_INVALID 0xffff /* indicates no jump generated */ uintptr_t jmp_target_arg[2]; /* target address or offset */ - /* Each TB has an associated circular list of TBs jumping to this one. - * jmp_list_first points to the first TB jumping to this one. - * jmp_list_next is used to point to the next TB in a list. - * Since each TB can have two jumps, it can participate in two lists. - * jmp_list_first and jmp_list_next are 4-byte aligned pointers to a - * TranslationBlock structure, but the two least significant bits of - * them are used to encode which data field of the pointed TB should - * be used to traverse the list further from that TB: - * 0 => jmp_list_next[0], 1 => jmp_list_next[1], 2 => jmp_list_first. - * In other words, 0/1 tells which jump is used in the pointed TB, - * and 2 means that this is a pointer back to the target TB of this list. + /* + * Each TB has a NULL-terminated list (jmp_list_head) of incoming jumps. + * Each TB can have two outgoing jumps, and therefore can participate + * in two lists. The list entries are kept in jmp_list_next[2]. The least + * significant bit (LSB) of the pointers in these lists is used to encode + * which of the two list entries is to be used in the pointed TB. + * + * List traversals are protected by jmp_lock. The destination TB of each + * outgoing jump is kept in jmp_dest[] so that the appropriate jmp_lock + * can be acquired from any origin TB. + * + * jmp_dest[] are tagged pointers as well. The LSB is set when the TB is + * being invalidated, so that no further outgoing jumps from it can be set. + * + * jmp_lock also protects the CF_INVALID cflag; a jump must not be chained + * to a destination TB that has CF_INVALID set. */ + uintptr_t jmp_list_head; uintptr_t jmp_list_next[2]; - uintptr_t jmp_list_first; + uintptr_t jmp_dest[2]; }; extern bool parallel_cpus; @@ -405,7 +415,6 @@ static inline uint32_t curr_cflags(void) | (use_icount ? CF_USE_ICOUNT : 0); } -void tb_remove(TranslationBlock *tb); void tb_flush(CPUState *cpu); void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr); TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc, @@ -431,9 +440,13 @@ extern uintptr_t tci_tb_ptr; smaller than 4 bytes, so we don't worry about special-casing this. */ #define GETPC_ADJ 2 -void tb_lock(void); -void tb_unlock(void); -void tb_lock_reset(void); +#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_DEBUG_TCG) +void assert_no_pages_locked(void); +#else +static inline void assert_no_pages_locked(void) +{ +} +#endif #if !defined(CONFIG_USER_ONLY) diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 56c25c0ef7..bb08fa4d2f 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -49,6 +49,8 @@ void mtree_print_dispatch(fprintf_function mon, void *f, struct AddressSpaceDispatch *d, MemoryRegion *root); +struct page_collection; + /* Opaque struct for passing info from memory_notdirty_write_prepare() * to memory_notdirty_write_complete(). Callers should treat all fields * as private, with the exception of @active. @@ -60,10 +62,10 @@ void mtree_print_dispatch(fprintf_function mon, void *f, */ typedef struct { CPUState *cpu; + struct page_collection *pages; ram_addr_t ram_addr; vaddr mem_vaddr; unsigned size; - bool locked; bool active; } NotDirtyInfo; @@ -91,7 +93,7 @@ typedef struct { * * This must only be called if we are using TCG; it will assert otherwise. * - * We may take a lock in the prepare call, so callers must ensure that + * We may take locks in the prepare call, so callers must ensure that * they don't exit (via longjump or otherwise) without calling complete. * * This call must only be made inside an RCU critical section. diff --git a/include/exec/tb-context.h b/include/exec/tb-context.h index 1d41202485..feb585e0a7 100644 --- a/include/exec/tb-context.h +++ b/include/exec/tb-context.h @@ -31,14 +31,10 @@ typedef struct TBContext TBContext; struct TBContext { - GTree *tb_tree; struct qht htable; - /* any access to the tbs or the page table must use this lock */ - QemuMutex tb_lock; /* statistics */ unsigned tb_flush_count; - int tb_phys_invalidate_count; }; extern TBContext tb_ctx; diff --git a/include/qemu/qht.h b/include/qemu/qht.h index 531aa95325..1fb9116fa0 100644 --- a/include/qemu/qht.h +++ b/include/qemu/qht.h @@ -11,8 +11,11 @@ #include "qemu/thread.h" #include "qemu/qdist.h" +typedef bool (*qht_cmp_func_t)(const void *a, const void *b); + struct qht { struct qht_map *map; + qht_cmp_func_t cmp; QemuMutex lock; /* serializes setters of ht->map */ unsigned int mode; }; @@ -47,10 +50,12 @@ typedef void (*qht_iter_func_t)(struct qht *ht, void *p, uint32_t h, void *up); /** * qht_init - Initialize a QHT * @ht: QHT to be initialized + * @cmp: default comparison function. Cannot be NULL. * @n_elems: number of entries the hash table should be optimized for. * @mode: bitmask with OR'ed QHT_MODE_* */ -void qht_init(struct qht *ht, size_t n_elems, unsigned int mode); +void qht_init(struct qht *ht, qht_cmp_func_t cmp, size_t n_elems, + unsigned int mode); /** * qht_destroy - destroy a previously initialized QHT @@ -65,6 +70,7 @@ void qht_destroy(struct qht *ht); * @ht: QHT to insert to * @p: pointer to be inserted * @hash: hash corresponding to @p + * @existing: address where the pointer to an existing entry can be copied to * * Attempting to insert a NULL @p is a bug. * Inserting the same pointer @p with different @hash values is a bug. @@ -73,16 +79,18 @@ void qht_destroy(struct qht *ht); * inserted into the hash table. * * Returns true on success. - * Returns false if the @p-@hash pair already exists in the hash table. + * Returns false if there is an existing entry in the table that is equivalent + * (i.e. ht->cmp matches and the hash is the same) to @p-@h. If @existing + * is !NULL, a pointer to this existing entry is copied to it. */ -bool qht_insert(struct qht *ht, void *p, uint32_t hash); +bool qht_insert(struct qht *ht, void *p, uint32_t hash, void **existing); /** - * qht_lookup - Look up a pointer in a QHT + * qht_lookup_custom - Look up a pointer using a custom comparison function. * @ht: QHT to be looked up - * @func: function to compare existing pointers against @userp * @userp: pointer to pass to @func * @hash: hash of the pointer to be looked up + * @func: function to compare existing pointers against @userp * * Needs to be called under an RCU read-critical section. * @@ -94,8 +102,18 @@ bool qht_insert(struct qht *ht, void *p, uint32_t hash); * Returns the corresponding pointer when a match is found. * Returns NULL otherwise. */ -void *qht_lookup(struct qht *ht, qht_lookup_func_t func, const void *userp, - uint32_t hash); +void *qht_lookup_custom(struct qht *ht, const void *userp, uint32_t hash, + qht_lookup_func_t func); + +/** + * qht_lookup - Look up a pointer in a QHT + * @ht: QHT to be looked up + * @userp: pointer to pass to the comparison function + * @hash: hash of the pointer to be looked up + * + * Calls qht_lookup_custom() using @ht's default comparison function. + */ +void *qht_lookup(struct qht *ht, const void *userp, uint32_t hash); /** * qht_remove - remove a pointer from the hash table |