Nothing really exciting: some groundwork for changing virtio endian, and
some robustness fixes for broken virtio devices, plus minor tweaks. [vs last pull request: added the virtio-scsi broken vq escape patch, which I somehow lost.] Cheers, Rusty. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.14 (GNU/Linux) iQIcBAABAgAGBQJSgDsJAAoJENkgDmzRrbjxEE4P/jXqZHS/HdlxW9k0BjKKlEIF PdtCoP3UhWTdskXvy2pD8m6nYn214MEJYUIa4HFlIEZsdxhuexzQHY19Ynkjagyv 57sRsUUm5fYQLIL7IUh2DUD1VU38hUFinno/y333szzvCj9qITDA/QABsiWxK8NO dq+Lmeixgrhc5yN9iryW+gZV+hekJIZ4LsU5ejSaJucKblzXUH8qIbmSthG7RTYJ tr4J7xTTXbhxY4CoC5Dpx2hvsFkvzaAIvI4Nr1mDjfq5cR8BaYvnC89U1IbhdAey p1AbZE58JLrY+Z8K8LBRGV2KjO8qSZ6R47hbZ9nAnodJYB7sZLyj6jUe1q+/htuC Dh9Xm9O4eW2xNaFk20dYeIF4UU5/HzdsbvG/IlH8x4sm8/K706ocYyAOHlzYUg2T k7gltrgDzDokMgb2R44gwnr4oaJ2q8Gne6JXswlPEv2eRs6vNnA5Xhc0rEHGkU6C gYn1vNFN6yx0vf2syG/Ce5pZtMxGpefKQkHzzWdq8FKr1B9s54dDuf2hls7J8A9t OQT1gE33yURSelf4Kh4k9zWXaWk/Ohv9l2R1cqpALnJ4/+q0fP5t7HdK500S7aax DxLeFeqvsBw7nlWgsGxQmt+fjITQFHhcDiwst0ehnt6RbDEW7XPIguz0K/gyhxYG +UNbl/5Gr64jnUX3YCzm =vY2L -----END PGP SIGNATURE----- Merge tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux Pull virtio updates from Rusty Russell: "Nothing really exciting: some groundwork for changing virtio endian, and some robustness fixes for broken virtio devices, plus minor tweaks" * tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux: virtio_scsi: verify if queue is broken after virtqueue_get_buf() x86, asmlinkage, lguest: Pass in globals into assembler statement virtio: mmio: fix signature checking for BE guests virtio_ring: adapt to notify() returning bool virtio_net: verify if queue is broken after virtqueue_get_buf() virtio_console: verify if queue is broken after virtqueue_get_buf() virtio_blk: verify if queue is broken after virtqueue_get_buf() virtio_ring: add new function virtqueue_is_broken() virtio_test: verify if virtqueue_kick() succeeded virtio_net: verify if virtqueue_kick() succeeded virtio_ring: let virtqueue_{kick()/notify()} return a bool virtio_ring: change host notification API virtio_config: remove virtio_config_val virtio: use size-based config accessors. virtio_config: introduce size-based accessors. virtio_ring: plug kmemleak false positive. virtio: pm: use CONFIG_PM_SLEEP instead of CONFIG_PM
This commit is contained in:
commit
b746f9c794
21 changed files with 310 additions and 166 deletions
|
@ -591,7 +591,8 @@ static bool try_fill_recv(struct receive_queue *rq, gfp_t gfp)
|
|||
} while (rq->vq->num_free);
|
||||
if (unlikely(rq->num > rq->max))
|
||||
rq->max = rq->num;
|
||||
virtqueue_kick(rq->vq);
|
||||
if (unlikely(!virtqueue_kick(rq->vq)))
|
||||
return false;
|
||||
return !oom;
|
||||
}
|
||||
|
||||
|
@ -797,7 +798,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
err = xmit_skb(sq, skb);
|
||||
|
||||
/* This should not happen! */
|
||||
if (unlikely(err)) {
|
||||
if (unlikely(err) || unlikely(!virtqueue_kick(sq->vq))) {
|
||||
dev->stats.tx_fifo_errors++;
|
||||
if (net_ratelimit())
|
||||
dev_warn(&dev->dev,
|
||||
|
@ -806,7 +807,6 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
kfree_skb(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
virtqueue_kick(sq->vq);
|
||||
|
||||
/* Don't wait up for transmitted skbs to be freed. */
|
||||
skb_orphan(skb);
|
||||
|
@ -865,12 +865,14 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
|
|||
BUG_ON(virtqueue_add_sgs(vi->cvq, sgs, out_num, in_num, vi, GFP_ATOMIC)
|
||||
< 0);
|
||||
|
||||
virtqueue_kick(vi->cvq);
|
||||
if (unlikely(!virtqueue_kick(vi->cvq)))
|
||||
return status == VIRTIO_NET_OK;
|
||||
|
||||
/* Spin for a response, the kick causes an ioport write, trapping
|
||||
* into the hypervisor, so the request should be handled immediately.
|
||||
*/
|
||||
while (!virtqueue_get_buf(vi->cvq, &tmp))
|
||||
while (!virtqueue_get_buf(vi->cvq, &tmp) &&
|
||||
!virtqueue_is_broken(vi->cvq))
|
||||
cpu_relax();
|
||||
|
||||
return status == VIRTIO_NET_OK;
|
||||
|
@ -898,8 +900,13 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p)
|
|||
return -EINVAL;
|
||||
}
|
||||
} else if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) {
|
||||
vdev->config->set(vdev, offsetof(struct virtio_net_config, mac),
|
||||
addr->sa_data, dev->addr_len);
|
||||
unsigned int i;
|
||||
|
||||
/* Naturally, this has an atomicity problem. */
|
||||
for (i = 0; i < dev->addr_len; i++)
|
||||
virtio_cwrite8(vdev,
|
||||
offsetof(struct virtio_net_config, mac) +
|
||||
i, addr->sa_data[i]);
|
||||
}
|
||||
|
||||
eth_commit_mac_addr_change(dev, p);
|
||||
|
@ -1281,9 +1288,8 @@ static void virtnet_config_changed_work(struct work_struct *work)
|
|||
if (!vi->config_enable)
|
||||
goto done;
|
||||
|
||||
if (virtio_config_val(vi->vdev, VIRTIO_NET_F_STATUS,
|
||||
offsetof(struct virtio_net_config, status),
|
||||
&v) < 0)
|
||||
if (virtio_cread_feature(vi->vdev, VIRTIO_NET_F_STATUS,
|
||||
struct virtio_net_config, status, &v) < 0)
|
||||
goto done;
|
||||
|
||||
if (v & VIRTIO_NET_S_ANNOUNCE) {
|
||||
|
@ -1507,9 +1513,9 @@ static int virtnet_probe(struct virtio_device *vdev)
|
|||
u16 max_queue_pairs;
|
||||
|
||||
/* Find if host supports multiqueue virtio_net device */
|
||||
err = virtio_config_val(vdev, VIRTIO_NET_F_MQ,
|
||||
offsetof(struct virtio_net_config,
|
||||
max_virtqueue_pairs), &max_queue_pairs);
|
||||
err = virtio_cread_feature(vdev, VIRTIO_NET_F_MQ,
|
||||
struct virtio_net_config,
|
||||
max_virtqueue_pairs, &max_queue_pairs);
|
||||
|
||||
/* We need at least 2 queue's */
|
||||
if (err || max_queue_pairs < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN ||
|
||||
|
@ -1561,9 +1567,11 @@ static int virtnet_probe(struct virtio_device *vdev)
|
|||
dev->vlan_features = dev->features;
|
||||
|
||||
/* Configuration may specify what MAC to use. Otherwise random. */
|
||||
if (virtio_config_val_len(vdev, VIRTIO_NET_F_MAC,
|
||||
offsetof(struct virtio_net_config, mac),
|
||||
dev->dev_addr, dev->addr_len) < 0)
|
||||
if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC))
|
||||
virtio_cread_bytes(vdev,
|
||||
offsetof(struct virtio_net_config, mac),
|
||||
dev->dev_addr, dev->addr_len);
|
||||
else
|
||||
eth_hw_addr_random(dev);
|
||||
|
||||
/* Set up our device-specific information */
|
||||
|
@ -1704,7 +1712,7 @@ static void virtnet_remove(struct virtio_device *vdev)
|
|||
free_netdev(vi->dev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int virtnet_freeze(struct virtio_device *vdev)
|
||||
{
|
||||
struct virtnet_info *vi = vdev->priv;
|
||||
|
@ -1795,7 +1803,7 @@ static struct virtio_driver virtio_net_driver = {
|
|||
.probe = virtnet_probe,
|
||||
.remove = virtnet_remove,
|
||||
.config_changed = virtnet_config_changed,
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.freeze = virtnet_freeze,
|
||||
.restore = virtnet_restore,
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue