util/qht: Document memory ordering assumptions
It is naturally expected that some memory ordering should be provided around qht_insert() and qht_lookup(). Document these assumptions in the header file and put some comments in the source to denote how that memory ordering requirements are fulfilled. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> [Sergey Fedorov: commit title and message provided; comment on qht_remove() elided] Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com> Message-Id: <20160715175852.30749-2-sergey.fedorov@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
		
							parent
							
								
									cc0100f464
								
							
						
					
					
						commit
						34506b30e4
					
				| 
						 | 
				
			
			@ -69,6 +69,9 @@ void qht_destroy(struct qht *ht);
 | 
			
		|||
 * Attempting to insert a NULL @p is a bug.
 | 
			
		||||
 * Inserting the same pointer @p with different @hash values is a bug.
 | 
			
		||||
 *
 | 
			
		||||
 * In case of successful operation, smp_wmb() is implied before the pointer is
 | 
			
		||||
 * inserted into the hash table.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns true on sucess.
 | 
			
		||||
 * Returns false if the @p-@hash pair already exists in the hash table.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +86,8 @@ bool qht_insert(struct qht *ht, void *p, uint32_t hash);
 | 
			
		|||
 *
 | 
			
		||||
 * Needs to be called under an RCU read-critical section.
 | 
			
		||||
 *
 | 
			
		||||
 * smp_read_barrier_depends() is implied before the call to @func.
 | 
			
		||||
 *
 | 
			
		||||
 * The user-provided @func compares pointers in QHT against @userp.
 | 
			
		||||
 * If the function returns true, a match has been found.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -445,7 +445,11 @@ void *qht_do_lookup(struct qht_bucket *head, qht_lookup_func_t func,
 | 
			
		|||
    do {
 | 
			
		||||
        for (i = 0; i < QHT_BUCKET_ENTRIES; i++) {
 | 
			
		||||
            if (b->hashes[i] == hash) {
 | 
			
		||||
                void *p = atomic_read(&b->pointers[i]);
 | 
			
		||||
                /* The pointer is dereferenced before seqlock_read_retry,
 | 
			
		||||
                 * so (unlike qht_insert__locked) we need to use
 | 
			
		||||
                 * atomic_rcu_read here.
 | 
			
		||||
                 */
 | 
			
		||||
                void *p = atomic_rcu_read(&b->pointers[i]);
 | 
			
		||||
 | 
			
		||||
                if (likely(p) && likely(func(p, userp))) {
 | 
			
		||||
                    return p;
 | 
			
		||||
| 
						 | 
				
			
			@ -535,6 +539,7 @@ static bool qht_insert__locked(struct qht *ht, struct qht_map *map,
 | 
			
		|||
        atomic_rcu_set(&prev->next, b);
 | 
			
		||||
    }
 | 
			
		||||
    b->hashes[i] = hash;
 | 
			
		||||
    /* smp_wmb() implicit in seqlock_write_begin.  */
 | 
			
		||||
    atomic_set(&b->pointers[i], p);
 | 
			
		||||
    seqlock_write_end(&head->sequence);
 | 
			
		||||
    return true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue