virtio_ring.c (03ab8e6297acd1bc0eedaa050e2a1635c576fd11) virtio_ring.c (35c51e093d956f6d058e193711c8d424817a44a9)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/* Virtio ring implementation.
3 *
4 * Copyright 2007 Rusty Russell IBM Corporation
5 */
6#include <linux/virtio.h>
7#include <linux/virtio_ring.h>
8#include <linux/virtio_config.h>

--- 191 unchanged lines hidden (view full) ---

200
201
202/*
203 * Helpers.
204 */
205
206#define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq)
207
1// SPDX-License-Identifier: GPL-2.0-or-later
2/* Virtio ring implementation.
3 *
4 * Copyright 2007 Rusty Russell IBM Corporation
5 */
6#include <linux/virtio.h>
7#include <linux/virtio_ring.h>
8#include <linux/virtio_config.h>

--- 191 unchanged lines hidden (view full) ---

200
201
202/*
203 * Helpers.
204 */
205
206#define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq)
207
208static inline bool virtqueue_use_indirect(struct virtqueue *_vq,
208static inline bool virtqueue_use_indirect(struct vring_virtqueue *vq,
209 unsigned int total_sg)
210{
209 unsigned int total_sg)
210{
211 struct vring_virtqueue *vq = to_vvq(_vq);
212
213 /*
214 * If the host supports indirect descriptor tables, and we have multiple
215 * buffers, then go indirect. FIXME: tune this threshold
216 */
217 return (vq->indirect && total_sg > 1 && vq->vq.num_free);
218}
219
220/*

--- 273 unchanged lines hidden (view full) ---

494 }
495
496 LAST_ADD_TIME_UPDATE(vq);
497
498 BUG_ON(total_sg == 0);
499
500 head = vq->free_head;
501
211 /*
212 * If the host supports indirect descriptor tables, and we have multiple
213 * buffers, then go indirect. FIXME: tune this threshold
214 */
215 return (vq->indirect && total_sg > 1 && vq->vq.num_free);
216}
217
218/*

--- 273 unchanged lines hidden (view full) ---

492 }
493
494 LAST_ADD_TIME_UPDATE(vq);
495
496 BUG_ON(total_sg == 0);
497
498 head = vq->free_head;
499
502 if (virtqueue_use_indirect(_vq, total_sg))
500 if (virtqueue_use_indirect(vq, total_sg))
503 desc = alloc_indirect_split(_vq, total_sg, gfp);
504 else {
505 desc = NULL;
506 WARN_ON_ONCE(total_sg > vq->split.vring.num && !vq->indirect);
507 }
508
509 if (desc) {
510 /* Use a single buffer which doesn't continue */

--- 662 unchanged lines hidden (view full) ---

1173 END_USE(vq);
1174 return -EIO;
1175 }
1176
1177 LAST_ADD_TIME_UPDATE(vq);
1178
1179 BUG_ON(total_sg == 0);
1180
501 desc = alloc_indirect_split(_vq, total_sg, gfp);
502 else {
503 desc = NULL;
504 WARN_ON_ONCE(total_sg > vq->split.vring.num && !vq->indirect);
505 }
506
507 if (desc) {
508 /* Use a single buffer which doesn't continue */

--- 662 unchanged lines hidden (view full) ---

1171 END_USE(vq);
1172 return -EIO;
1173 }
1174
1175 LAST_ADD_TIME_UPDATE(vq);
1176
1177 BUG_ON(total_sg == 0);
1178
1181 if (virtqueue_use_indirect(_vq, total_sg)) {
1179 if (virtqueue_use_indirect(vq, total_sg)) {
1182 err = virtqueue_add_indirect_packed(vq, sgs, total_sg, out_sgs,
1183 in_sgs, data, gfp);
1184 if (err != -ENOMEM) {
1185 END_USE(vq);
1186 return err;
1187 }
1188
1189 /* fall back on direct */

--- 1259 unchanged lines hidden ---
1180 err = virtqueue_add_indirect_packed(vq, sgs, total_sg, out_sgs,
1181 in_sgs, data, gfp);
1182 if (err != -ENOMEM) {
1183 END_USE(vq);
1184 return err;
1185 }
1186
1187 /* fall back on direct */

--- 1259 unchanged lines hidden ---