| 224 | } |
| 225 | |
| 226 | static __rte_always_inline void |
| 227 | vhost_log_cache_page(struct virtio_net *dev, struct vhost_virtqueue *vq, |
| 228 | uint64_t page) |
| 229 | { |
| 230 | uint32_t bit_nr = page % (sizeof(unsigned long) << 3); |
| 231 | uint32_t offset = page / (sizeof(unsigned long) << 3); |
| 232 | int i; |
| 233 | |
| 234 | if (unlikely(!vq->log_cache)) { |
| 235 | /* No logging cache allocated, write dirty log map directly */ |
| 236 | rte_atomic_thread_fence(rte_memory_order_release); |
| 237 | vhost_log_page((uint8_t *)(uintptr_t)dev->log_base, page); |
| 238 | |
| 239 | return; |
| 240 | } |
| 241 | |
| 242 | for (i = 0; i < vq->log_cache_nb_elem; i++) { |
| 243 | struct log_cache_entry *elem = vq->log_cache + i; |
| 244 | |
| 245 | if (elem->offset == offset) { |
| 246 | elem->val |= (1UL << bit_nr); |
| 247 | return; |
| 248 | } |
| 249 | } |
| 250 | |
| 251 | if (unlikely(i >= VHOST_LOG_CACHE_NR)) { |
| 252 | /* |
| 253 | * No more room for a new log cache entry, |
| 254 | * so write the dirty log map directly. |
| 255 | */ |
| 256 | rte_atomic_thread_fence(rte_memory_order_release); |
| 257 | vhost_log_page((uint8_t *)(uintptr_t)dev->log_base, page); |
| 258 | |
| 259 | return; |
| 260 | } |
| 261 | |
| 262 | vq->log_cache[i].offset = offset; |
| 263 | vq->log_cache[i].val = (1UL << bit_nr); |
| 264 | vq->log_cache_nb_elem++; |
| 265 | } |
| 266 | |
| 267 | void |
| 268 | __vhost_log_cache_write(struct virtio_net *dev, struct vhost_virtqueue *vq, |
no test coverage detected