diff options
| author | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
| commit | 1ac731c529cd4d6adbce134754b51ff7d822b145 (patch) | |
| tree | 143ab3f35ca5f3b69f583c84e6964b17139c2ec1 /drivers/virtio/virtio_ring.c | |
| parent | 07b4c950f27bef0362dc6ad7ee713aab61d58149 (diff) | |
| parent | 54116d442e001e1b6bd482122043b1870998a1f3 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.6 merge window.
Diffstat (limited to 'drivers/virtio/virtio_ring.c')
| -rw-r--r-- | drivers/virtio/virtio_ring.c | 89 | 
1 files changed, 59 insertions, 30 deletions
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 41144b5246a8..c5310eaf8b46 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -231,10 +231,10 @@ static void vring_free(struct virtqueue *_vq);   * Helpers.   */ -#define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq) +#define to_vvq(_vq) container_of_const(_vq, struct vring_virtqueue, vq) -static inline bool virtqueue_use_indirect(struct vring_virtqueue *vq, -					  unsigned int total_sg) +static bool virtqueue_use_indirect(const struct vring_virtqueue *vq, +				   unsigned int total_sg)  {  	/*  	 * If the host supports indirect descriptor tables, and we have multiple @@ -269,7 +269,7 @@ static inline bool virtqueue_use_indirect(struct vring_virtqueue *vq,   * unconditionally on data path.   */ -static bool vring_use_dma_api(struct virtio_device *vdev) +static bool vring_use_dma_api(const struct virtio_device *vdev)  {  	if (!virtio_has_dma_quirk(vdev))  		return true; @@ -289,7 +289,7 @@ static bool vring_use_dma_api(struct virtio_device *vdev)  	return false;  } -size_t virtio_max_dma_size(struct virtio_device *vdev) +size_t virtio_max_dma_size(const struct virtio_device *vdev)  {  	size_t max_segment_size = SIZE_MAX; @@ -349,7 +349,7 @@ static void vring_free_queue(struct virtio_device *vdev, size_t size,   * making all of the arch DMA ops work on the vring device itself   * is a mess.   */ -static inline struct device *vring_dma_dev(const struct vring_virtqueue *vq) +static struct device *vring_dma_dev(const struct vring_virtqueue *vq)  {  	return vq->dma_dev;  } @@ -423,7 +423,7 @@ static void virtqueue_init(struct vring_virtqueue *vq, u32 num)   */  static void vring_unmap_one_split_indirect(const struct vring_virtqueue *vq, -					   struct vring_desc *desc) +					   const struct vring_desc *desc)  {  	u16 flags; @@ -784,7 +784,7 @@ static void detach_buf_split(struct vring_virtqueue *vq, unsigned int head,  	}  } -static inline bool more_used_split(const struct vring_virtqueue *vq) +static bool more_used_split(const struct vring_virtqueue *vq)  {  	return vq->last_used_idx != virtio16_to_cpu(vq->vq.vdev,  			vq->split.vring.used->idx); @@ -854,6 +854,14 @@ static void virtqueue_disable_cb_split(struct virtqueue *_vq)  	if (!(vq->split.avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT)) {  		vq->split.avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT; + +		/* +		 * If device triggered an event already it won't trigger one again: +		 * no need to disable. +		 */ +		if (vq->event_triggered) +			return; +  		if (vq->event)  			/* TODO: this is a hack. Figure out a cleaner value to write. */  			vring_used_event(&vq->split.vring) = 0x0; @@ -1172,18 +1180,18 @@ err:  /*   * Packed ring specific functions - *_packed().   */ -static inline bool packed_used_wrap_counter(u16 last_used_idx) +static bool packed_used_wrap_counter(u16 last_used_idx)  {  	return !!(last_used_idx & (1 << VRING_PACKED_EVENT_F_WRAP_CTR));  } -static inline u16 packed_last_used(u16 last_used_idx) +static u16 packed_last_used(u16 last_used_idx)  {  	return last_used_idx & ~(-(1 << VRING_PACKED_EVENT_F_WRAP_CTR));  }  static void vring_unmap_extra_packed(const struct vring_virtqueue *vq, -				     struct vring_desc_extra *extra) +				     const struct vring_desc_extra *extra)  {  	u16 flags; @@ -1206,7 +1214,7 @@ static void vring_unmap_extra_packed(const struct vring_virtqueue *vq,  }  static void vring_unmap_desc_packed(const struct vring_virtqueue *vq, -				   struct vring_packed_desc *desc) +				    const struct vring_packed_desc *desc)  {  	u16 flags; @@ -1612,7 +1620,7 @@ static inline bool is_used_desc_packed(const struct vring_virtqueue *vq,  	return avail == used && used == used_wrap_counter;  } -static inline bool more_used_packed(const struct vring_virtqueue *vq) +static bool more_used_packed(const struct vring_virtqueue *vq)  {  	u16 last_used;  	u16 last_used_idx; @@ -1699,6 +1707,14 @@ static void virtqueue_disable_cb_packed(struct virtqueue *_vq)  	if (vq->packed.event_flags_shadow != VRING_PACKED_EVENT_FLAG_DISABLE) {  		vq->packed.event_flags_shadow = VRING_PACKED_EVENT_FLAG_DISABLE; + +		/* +		 * If device triggered an event already it won't trigger one again: +		 * no need to disable. +		 */ +		if (vq->event_triggered) +			return; +  		vq->packed.vring.driver->flags =  			cpu_to_le16(vq->packed.event_flags_shadow);  	} @@ -2330,12 +2346,6 @@ void virtqueue_disable_cb(struct virtqueue *_vq)  {  	struct vring_virtqueue *vq = to_vvq(_vq); -	/* If device triggered an event already it won't trigger one again: -	 * no need to disable. -	 */ -	if (vq->event_triggered) -		return; -  	if (vq->packed_ring)  		virtqueue_disable_cb_packed(_vq);  	else @@ -2752,6 +2762,23 @@ void vring_del_virtqueue(struct virtqueue *_vq)  }  EXPORT_SYMBOL_GPL(vring_del_virtqueue); +u32 vring_notification_data(struct virtqueue *_vq) +{ +	struct vring_virtqueue *vq = to_vvq(_vq); +	u16 next; + +	if (vq->packed_ring) +		next = (vq->packed.next_avail_idx & +				~(-(1 << VRING_PACKED_EVENT_F_WRAP_CTR))) | +			vq->packed.avail_wrap_counter << +				VRING_PACKED_EVENT_F_WRAP_CTR; +	else +		next = vq->split.avail_idx_shadow; + +	return next << 16 | _vq->index; +} +EXPORT_SYMBOL_GPL(vring_notification_data); +  /* Manipulates transport-specific feature bits. */  void vring_transport_features(struct virtio_device *vdev)  { @@ -2771,6 +2798,8 @@ void vring_transport_features(struct virtio_device *vdev)  			break;  		case VIRTIO_F_ORDER_PLATFORM:  			break; +		case VIRTIO_F_NOTIFICATION_DATA: +			break;  		default:  			/* We don't understand this bit. */  			__virtio_clear_bit(vdev, i); @@ -2786,10 +2815,10 @@ EXPORT_SYMBOL_GPL(vring_transport_features);   * Returns the size of the vring.  This is mainly used for boasting to   * userspace.  Unlike other operations, this need not be serialized.   */ -unsigned int virtqueue_get_vring_size(struct virtqueue *_vq) +unsigned int virtqueue_get_vring_size(const struct virtqueue *_vq)  { -	struct vring_virtqueue *vq = to_vvq(_vq); +	const struct vring_virtqueue *vq = to_vvq(_vq);  	return vq->packed_ring ? vq->packed.vring.num : vq->split.vring.num;  } @@ -2819,9 +2848,9 @@ void __virtqueue_unbreak(struct virtqueue *_vq)  }  EXPORT_SYMBOL_GPL(__virtqueue_unbreak); -bool virtqueue_is_broken(struct virtqueue *_vq) +bool virtqueue_is_broken(const struct virtqueue *_vq)  { -	struct vring_virtqueue *vq = to_vvq(_vq); +	const struct vring_virtqueue *vq = to_vvq(_vq);  	return READ_ONCE(vq->broken);  } @@ -2868,9 +2897,9 @@ void __virtio_unbreak_device(struct virtio_device *dev)  }  EXPORT_SYMBOL_GPL(__virtio_unbreak_device); -dma_addr_t virtqueue_get_desc_addr(struct virtqueue *_vq) +dma_addr_t virtqueue_get_desc_addr(const struct virtqueue *_vq)  { -	struct vring_virtqueue *vq = to_vvq(_vq); +	const struct vring_virtqueue *vq = to_vvq(_vq);  	BUG_ON(!vq->we_own_ring); @@ -2881,9 +2910,9 @@ dma_addr_t virtqueue_get_desc_addr(struct virtqueue *_vq)  }  EXPORT_SYMBOL_GPL(virtqueue_get_desc_addr); -dma_addr_t virtqueue_get_avail_addr(struct virtqueue *_vq) +dma_addr_t virtqueue_get_avail_addr(const struct virtqueue *_vq)  { -	struct vring_virtqueue *vq = to_vvq(_vq); +	const struct vring_virtqueue *vq = to_vvq(_vq);  	BUG_ON(!vq->we_own_ring); @@ -2895,9 +2924,9 @@ dma_addr_t virtqueue_get_avail_addr(struct virtqueue *_vq)  }  EXPORT_SYMBOL_GPL(virtqueue_get_avail_addr); -dma_addr_t virtqueue_get_used_addr(struct virtqueue *_vq) +dma_addr_t virtqueue_get_used_addr(const struct virtqueue *_vq)  { -	struct vring_virtqueue *vq = to_vvq(_vq); +	const struct vring_virtqueue *vq = to_vvq(_vq);  	BUG_ON(!vq->we_own_ring); @@ -2910,7 +2939,7 @@ dma_addr_t virtqueue_get_used_addr(struct virtqueue *_vq)  EXPORT_SYMBOL_GPL(virtqueue_get_used_addr);  /* Only available for split ring */ -const struct vring *virtqueue_get_vring(struct virtqueue *vq) +const struct vring *virtqueue_get_vring(const struct virtqueue *vq)  {  	return &to_vvq(vq)->split.vring;  }  |