Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-f…
Browse files Browse the repository at this point in the history
…or-linus

* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
  virtio_net: delay TX callbacks
  virtio: add api for delayed callbacks
  virtio_test: support event index
  vhost: support event index
  virtio_ring: support event idx feature
  virtio ring: inline function to check for events
  virtio: event index interface
  virtio: add full three-clause BSD text to headers.
  virtio balloon: kill tell-host-first logic
  virtio console: don't manually set or finalize VIRTIO_CONSOLE_F_MULTIPORT.
  drivers, block: virtio_blk: Replace cryptic number with the macro
  virtio_blk: allow re-reading config space at runtime
  lguest: remove support for VIRTIO_F_NOTIFY_ON_EMPTY.
  lguest: fix up compilation after move
  lguest: fix timer interrupt setup
  • Loading branch information
Linus Torvalds committed May 31, 2011
2 parents 850761b + 7a66f78 commit e12ca23
Show file tree
Hide file tree
Showing 23 changed files with 539 additions and 113 deletions.
2 changes: 1 addition & 1 deletion Documentation/virtual/lguest/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# This creates the demonstration utility "lguest" which runs a Linux guest.
# Missing headers? Add "-I../../include -I../../arch/x86/include"
# Missing headers? Add "-I../../../include -I../../../arch/x86/include"
CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE

all: lguest
Expand Down
22 changes: 2 additions & 20 deletions Documentation/virtual/lguest/lguest.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
#include <linux/virtio_rng.h>
#include <linux/virtio_ring.h>
#include <asm/bootparam.h>
#include "../../include/linux/lguest_launcher.h"
#include "../../../include/linux/lguest_launcher.h"
/*L:110
* We can ignore the 42 include files we need for this program, but I do want
* to draw attention to the use of kernel-style types.
Expand Down Expand Up @@ -135,9 +135,6 @@ struct device {
/* Is it operational */
bool running;

/* Does Guest want an intrrupt on empty? */
bool irq_on_empty;

/* Device-specific data. */
void *priv;
};
Expand Down Expand Up @@ -637,10 +634,7 @@ static void trigger_irq(struct virtqueue *vq)

/* If they don't want an interrupt, don't send one... */
if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) {
/* ... unless they've asked us to force one on empty. */
if (!vq->dev->irq_on_empty
|| lg_last_avail(vq) != vq->vring.avail->idx)
return;
return;
}

/* Send the Guest an interrupt tell them we used something up. */
Expand Down Expand Up @@ -1057,15 +1051,6 @@ static void create_thread(struct virtqueue *vq)
close(vq->eventfd);
}

static bool accepted_feature(struct device *dev, unsigned int bit)
{
const u8 *features = get_feature_bits(dev) + dev->feature_len;

if (dev->feature_len < bit / CHAR_BIT)
return false;
return features[bit / CHAR_BIT] & (1 << (bit % CHAR_BIT));
}

static void start_device(struct device *dev)
{
unsigned int i;
Expand All @@ -1079,8 +1064,6 @@ static void start_device(struct device *dev)
verbose(" %02x", get_feature_bits(dev)
[dev->feature_len+i]);

dev->irq_on_empty = accepted_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY);

for (vq = dev->vq; vq; vq = vq->next) {
if (vq->service)
create_thread(vq);
Expand Down Expand Up @@ -1564,7 +1547,6 @@ static void setup_tun_net(char *arg)
/* Set up the tun device. */
configure_device(ipfd, tapif, ip);

add_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY);
/* Expect Guest to handle everything except UFO */
add_feature(dev, VIRTIO_NET_F_CSUM);
add_feature(dev, VIRTIO_NET_F_GUEST_CSUM);
Expand Down
1 change: 1 addition & 0 deletions arch/x86/lguest/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,7 @@ static void lguest_time_irq(unsigned int irq, struct irq_desc *desc)
static void lguest_time_init(void)
{
/* Set up the timer interrupt (0) to go to our simple timer routine */
lguest_setup_irq(0);
irq_set_handler(0, lguest_time_irq);

clocksource_register_hz(&lguest_clock, NSEC_PER_SEC);
Expand Down
91 changes: 80 additions & 11 deletions drivers/block/virtio_blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
#include <linux/virtio.h>
#include <linux/virtio_blk.h>
#include <linux/scatterlist.h>
#include <linux/string_helpers.h>
#include <scsi/scsi_cmnd.h>

#define PART_BITS 4

static int major, index;
struct workqueue_struct *virtblk_wq;

struct virtio_blk
{
Expand All @@ -26,6 +29,9 @@ struct virtio_blk

mempool_t *pool;

/* Process context for config space updates */
struct work_struct config_work;

/* What host tells us, plus 2 for header & tailer. */
unsigned int sg_elems;

Expand Down Expand Up @@ -141,7 +147,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
num = blk_rq_map_sg(q, vbr->req, vblk->sg + out);

if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) {
sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, 96);
sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, SCSI_SENSE_BUFFERSIZE);
sg_set_buf(&vblk->sg[num + out + in++], &vbr->in_hdr,
sizeof(vbr->in_hdr));
}
Expand Down Expand Up @@ -291,6 +297,46 @@ static ssize_t virtblk_serial_show(struct device *dev,
}
DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL);

static void virtblk_config_changed_work(struct work_struct *work)
{
struct virtio_blk *vblk =
container_of(work, struct virtio_blk, config_work);
struct virtio_device *vdev = vblk->vdev;
struct request_queue *q = vblk->disk->queue;
char cap_str_2[10], cap_str_10[10];
u64 capacity, size;

/* Host must always specify the capacity. */
vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity),
&capacity, sizeof(capacity));

/* If capacity is too big, truncate with warning. */
if ((sector_t)capacity != capacity) {
dev_warn(&vdev->dev, "Capacity %llu too large: truncating\n",
(unsigned long long)capacity);
capacity = (sector_t)-1;
}

size = capacity * queue_logical_block_size(q);
string_get_size(size, STRING_UNITS_2, cap_str_2, sizeof(cap_str_2));
string_get_size(size, STRING_UNITS_10, cap_str_10, sizeof(cap_str_10));

dev_notice(&vdev->dev,
"new size: %llu %d-byte logical blocks (%s/%s)\n",
(unsigned long long)capacity,
queue_logical_block_size(q),
cap_str_10, cap_str_2);

set_capacity(vblk->disk, capacity);
}

static void virtblk_config_changed(struct virtio_device *vdev)
{
struct virtio_blk *vblk = vdev->priv;

queue_work(virtblk_wq, &vblk->config_work);
}

static int __devinit virtblk_probe(struct virtio_device *vdev)
{
struct virtio_blk *vblk;
Expand Down Expand Up @@ -327,6 +373,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
vblk->vdev = vdev;
vblk->sg_elems = sg_elems;
sg_init_table(vblk->sg, vblk->sg_elems);
INIT_WORK(&vblk->config_work, virtblk_config_changed_work);

/* We expect one virtqueue, for output. */
vblk->vq = virtio_find_single_vq(vdev, blk_done, "requests");
Expand Down Expand Up @@ -477,6 +524,8 @@ static void __devexit virtblk_remove(struct virtio_device *vdev)
{
struct virtio_blk *vblk = vdev->priv;

flush_work(&vblk->config_work);

/* Nothing should be pending. */
BUG_ON(!list_empty(&vblk->reqs));

Expand Down Expand Up @@ -508,27 +557,47 @@ static unsigned int features[] = {
* Use __refdata to avoid this warning.
*/
static struct virtio_driver __refdata virtio_blk = {
.feature_table = features,
.feature_table_size = ARRAY_SIZE(features),
.driver.name = KBUILD_MODNAME,
.driver.owner = THIS_MODULE,
.id_table = id_table,
.probe = virtblk_probe,
.remove = __devexit_p(virtblk_remove),
.feature_table = features,
.feature_table_size = ARRAY_SIZE(features),
.driver.name = KBUILD_MODNAME,
.driver.owner = THIS_MODULE,
.id_table = id_table,
.probe = virtblk_probe,
.remove = __devexit_p(virtblk_remove),
.config_changed = virtblk_config_changed,
};

static int __init init(void)
{
int error;

virtblk_wq = alloc_workqueue("virtio-blk", 0, 0);
if (!virtblk_wq)
return -ENOMEM;

major = register_blkdev(0, "virtblk");
if (major < 0)
return major;
return register_virtio_driver(&virtio_blk);
if (major < 0) {
error = major;
goto out_destroy_workqueue;
}

error = register_virtio_driver(&virtio_blk);
if (error)
goto out_unregister_blkdev;
return 0;

out_unregister_blkdev:
unregister_blkdev(major, "virtblk");
out_destroy_workqueue:
destroy_workqueue(virtblk_wq);
return error;
}

static void __exit fini(void)
{
unregister_blkdev(major, "virtblk");
unregister_virtio_driver(&virtio_blk);
destroy_workqueue(virtblk_wq);
}
module_init(init);
module_exit(fini);
Expand Down
5 changes: 0 additions & 5 deletions drivers/char/virtio_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -1677,17 +1677,12 @@ static int __devinit virtcons_probe(struct virtio_device *vdev)
portdev->config.max_nr_ports = 1;
if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) {
multiport = true;
vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT;

vdev->config->get(vdev, offsetof(struct virtio_console_config,
max_nr_ports),
&portdev->config.max_nr_ports,
sizeof(portdev->config.max_nr_ports));
}

/* Let the Host know we support multiple ports.*/
vdev->config->finalize_features(vdev);

err = init_vqs(portdev);
if (err < 0) {
dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/virtio_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
* before it gets out of hand. Naturally, this wastes entries. */
if (capacity < 2+MAX_SKB_FRAGS) {
netif_stop_queue(dev);
if (unlikely(!virtqueue_enable_cb(vi->svq))) {
if (unlikely(!virtqueue_enable_cb_delayed(vi->svq))) {
/* More just got used, free them then recheck. */
capacity += free_old_xmit_skbs(vi);
if (capacity >= 2+MAX_SKB_FRAGS) {
Expand Down
12 changes: 6 additions & 6 deletions drivers/vhost/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ static void handle_tx(struct vhost_net *net)
}

mutex_lock(&vq->mutex);
vhost_disable_notify(vq);
vhost_disable_notify(&net->dev, vq);

if (wmem < sock->sk->sk_sndbuf / 2)
tx_poll_stop(net);
Expand All @@ -166,8 +166,8 @@ static void handle_tx(struct vhost_net *net)
set_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
break;
}
if (unlikely(vhost_enable_notify(vq))) {
vhost_disable_notify(vq);
if (unlikely(vhost_enable_notify(&net->dev, vq))) {
vhost_disable_notify(&net->dev, vq);
continue;
}
break;
Expand Down Expand Up @@ -315,7 +315,7 @@ static void handle_rx(struct vhost_net *net)
return;

mutex_lock(&vq->mutex);
vhost_disable_notify(vq);
vhost_disable_notify(&net->dev, vq);
vhost_hlen = vq->vhost_hlen;
sock_hlen = vq->sock_hlen;

Expand All @@ -334,10 +334,10 @@ static void handle_rx(struct vhost_net *net)
break;
/* OK, now we need to know about added descriptors. */
if (!headcount) {
if (unlikely(vhost_enable_notify(vq))) {
if (unlikely(vhost_enable_notify(&net->dev, vq))) {
/* They have slipped one in as we were
* doing that: check again. */
vhost_disable_notify(vq);
vhost_disable_notify(&net->dev, vq);
continue;
}
/* Nothing new? Wait for eventfd to tell us
Expand Down
6 changes: 3 additions & 3 deletions drivers/vhost/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static void handle_vq(struct vhost_test *n)
return;

mutex_lock(&vq->mutex);
vhost_disable_notify(vq);
vhost_disable_notify(&n->dev, vq);

for (;;) {
head = vhost_get_vq_desc(&n->dev, vq, vq->iov,
Expand All @@ -61,8 +61,8 @@ static void handle_vq(struct vhost_test *n)
break;
/* Nothing new? Wait for eventfd to tell us they refilled. */
if (head == vq->num) {
if (unlikely(vhost_enable_notify(vq))) {
vhost_disable_notify(vq);
if (unlikely(vhost_enable_notify(&n->dev, vq))) {
vhost_disable_notify(&n->dev, vq);
continue;
}
break;
Expand Down
Loading

0 comments on commit e12ca23

Please sign in to comment.