From 59d4a43cb3ecdfd213d7dbc5877cbc2655c7e5dc Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Fri, 13 Jun 2008 13:46:41 +0100 Subject: virtio: Complete feature negotation before updating status lguest (in rusty's use-tun-ringfd patch) assumes that the guest has updated its feature bits before setting its status to VIRTIO_CONFIG_S_DRIVER_OK. That's pretty reasonable, so let's make it so. Signed-off-by: Mark McLoughlin Signed-off-by: Rusty Russell --- drivers/virtio/virtio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 0f3c2bb7bf35..7084e7e146c0 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c @@ -124,9 +124,9 @@ static int virtio_dev_probe(struct device *_d) if (err) add_status(dev, VIRTIO_CONFIG_S_FAILED); else { - add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); /* They should never have set feature bits beyond 32 */ dev->config->set_features(dev, dev->features[0]); + add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); } return err; } -- cgit v1.2.3 From d320102d754282b7f79d1bdf89b3d8206afd8fc7 Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Fri, 13 Jun 2008 13:46:40 +0100 Subject: virtio: Use bus_type probe and remove methods Hook up to the probe() and remove() methods in bus_type rather than device_driver. The latter has been preferred since 2.6.16. Signed-off-by: Mark McLoughlin Signed-off-by: Rusty Russell --- drivers/virtio/virtio.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index 7084e7e146c0..fc85cba64578 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c @@ -71,13 +71,6 @@ static int virtio_uevent(struct device *_dv, struct kobj_uevent_env *env) dev->id.device, dev->id.vendor); } -static struct bus_type virtio_bus = { - .name = "virtio", - .match = virtio_dev_match, - .dev_attrs = virtio_dev_attrs, - .uevent = virtio_uevent, -}; - static void add_status(struct virtio_device *dev, unsigned status) { dev->config->set_status(dev, dev->config->get_status(dev) | status); @@ -147,13 +140,20 @@ static int virtio_dev_remove(struct device *_d) return 0; } +static struct bus_type virtio_bus = { + .name = "virtio", + .match = virtio_dev_match, + .dev_attrs = virtio_dev_attrs, + .uevent = virtio_uevent, + .probe = virtio_dev_probe, + .remove = virtio_dev_remove, +}; + int register_virtio_driver(struct virtio_driver *driver) { /* Catch this early. */ BUG_ON(driver->feature_table_size && !driver->feature_table); driver->driver.bus = &virtio_bus; - driver->driver.probe = virtio_dev_probe; - driver->driver.remove = virtio_dev_remove; return driver_register(&driver->driver); } EXPORT_SYMBOL_GPL(register_virtio_driver); -- cgit v1.2.3 From a798a98de7e38c5ddcf15d05b7db854457693d1c Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Tue, 27 May 2008 12:06:26 +0100 Subject: virtio: fix virtio_net xmit of freed skb bug On Mon, 2008-05-26 at 17:42 +1000, Rusty Russell wrote: > If we fail to transmit a packet, we assume the queue is full and put > the skb into last_xmit_skb. However, if more space frees up before we > xmit it, we loop, and the result can be transmitting the same skb twice. > > Fix is simple: set skb to NULL if we've used it in some way, and check > before sending. ... > diff -r 564237b31993 drivers/net/virtio_net.c > --- a/drivers/net/virtio_net.c Mon May 19 12:22:00 2008 +1000 > +++ b/drivers/net/virtio_net.c Mon May 19 12:24:58 2008 +1000 > @@ -287,21 +287,25 @@ again: > free_old_xmit_skbs(vi); > > /* If we has a buffer left over from last time, send it now. */ > - if (vi->last_xmit_skb) { > + if (unlikely(vi->last_xmit_skb)) { > if (xmit_skb(vi, vi->last_xmit_skb) != 0) { > /* Drop this skb: we only queue one. */ > vi->dev->stats.tx_dropped++; > kfree_skb(skb); > + skb = NULL; > goto stop_queue; > } > vi->last_xmit_skb = NULL; With this, may drop an skb and then later in the function discover that we could have sent it after all. Poor wee skb :) How about the incremental patch below? Cheers, Mark. Subject: [PATCH] virtio_net: Delay dropping tx skbs Currently we drop the skb in start_xmit() if we have a queued buffer and fail to transmit it. However, if we delay dropping it until we've stopped the queue and enabled the tx notification callback, then there is a chance space might become available for it. Signed-off-by: Mark McLoughlin Signed-off-by: Rusty Russell --- drivers/net/virtio_net.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 4452306d5328..1ce6e5bce2e1 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -335,16 +335,11 @@ again: free_old_xmit_skbs(vi); /* If we has a buffer left over from last time, send it now. */ - if (unlikely(vi->last_xmit_skb)) { - if (xmit_skb(vi, vi->last_xmit_skb) != 0) { - /* Drop this skb: we only queue one. */ - vi->dev->stats.tx_dropped++; - kfree_skb(skb); - skb = NULL; - goto stop_queue; - } - vi->last_xmit_skb = NULL; - } + if (unlikely(vi->last_xmit_skb) && + xmit_skb(vi, vi->last_xmit_skb) != 0) + goto stop_queue; + + vi->last_xmit_skb = NULL; /* Put new one in send queue and do transmit */ if (likely(skb)) { @@ -370,6 +365,11 @@ stop_queue: netif_start_queue(dev); goto again; } + if (skb) { + /* Drop this skb: we only queue one. */ + vi->dev->stats.tx_dropped++; + kfree_skb(skb); + } goto done; } -- cgit v1.2.3 From b3798f258c1fa26404ca0441113355e39f380024 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 9 Jun 2008 16:22:48 -0700 Subject: lguest: use cpu capability accessors To support my little make-x86-bitops-use-proper-typechecking projectlet. Cc: Thomas Gleixner Cc: Andrea Arcangeli Signed-off-by: Andrew Morton Acked-by: Ingo Molnar Signed-off-by: Rusty Russell --- drivers/lguest/x86/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index 5126d5d9ea0e..996c78f98e88 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c @@ -477,7 +477,7 @@ void __init lguest_arch_host_init(void) * bit on its CPU, depending on the argument (0 == unset). */ on_each_cpu(adjust_pge, (void *)0, 0, 1); /* Turn off the feature in the global feature set. */ - clear_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability); + clear_cpu_cap(&boot_cpu_data, X86_FEATURE_PGE); } put_online_cpus(); }; @@ -488,7 +488,7 @@ void __exit lguest_arch_host_fini(void) /* If we had PGE before we started, turn it back on now. */ get_online_cpus(); if (cpu_had_pge) { - set_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability); + set_cpu_cap(&boot_cpu_data, X86_FEATURE_PGE); /* adjust_pge's argument "1" means set PGE. */ on_each_cpu(adjust_pge, (void *)1, 0, 1); } -- cgit v1.2.3 From 4cfdf7a65c6bbfa3d441d5f6712717e8c04a70fc Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 18 Apr 2008 11:21:42 +0800 Subject: virtio net: Add ethtool ops for SG/GSO This patch adds some basic ethtool operations to virtio_net so I could test SG without GSO (which was really useful because TSO turned out to be buggy :) Signed-off-by: Rusty Russell (remove MTU setting) --- drivers/net/virtio_net.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 1ce6e5bce2e1..e09a6d4233f2 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -19,6 +19,7 @@ //#define DEBUG #include #include +#include #include #include #include @@ -408,6 +409,22 @@ static int virtnet_close(struct net_device *dev) return 0; } +static int virtnet_set_tx_csum(struct net_device *dev, u32 data) +{ + struct virtnet_info *vi = netdev_priv(dev); + struct virtio_device *vdev = vi->vdev; + + if (data && !virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) + return -ENOSYS; + + return ethtool_op_set_tx_hw_csum(dev, data); +} + +static struct ethtool_ops virtnet_ethtool_ops = { + .set_tx_csum = virtnet_set_tx_csum, + .set_sg = ethtool_op_set_sg, +}; + static int virtnet_probe(struct virtio_device *vdev) { int err; @@ -427,6 +444,7 @@ static int virtnet_probe(struct virtio_device *vdev) #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = virtnet_netpoll; #endif + SET_ETHTOOL_OPS(dev, &virtnet_ethtool_ops); SET_NETDEV_DEV(dev, &vdev->dev); /* Do we support "hardware" checksums? */ -- cgit v1.2.3 From f64155e6aed6005edb12c281e5a0b71679ab3834 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 18 Apr 2008 11:24:27 +0800 Subject: virtio net: Allow receiving SG packets Finally this patch lets virtio_net receive GSO packets in addition to sending them. This can definitely be optimised for the non-GSO case. For comparison the Xen approach stores one page in each skb and uses subsequent skb's pages to construct an SG skb instead of preallocating the maximum amount of pages per skb. Signed-off-by: Rusty Russell (added feature bits) --- drivers/net/virtio_net.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index e09a6d4233f2..851927f4bb69 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -89,6 +89,7 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, unsigned len) { struct virtio_net_hdr *hdr = skb_vnet_hdr(skb); + int err; if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) { pr_debug("%s: short packet %i\n", dev->name, len); @@ -96,10 +97,14 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, goto drop; } len -= sizeof(struct virtio_net_hdr); - BUG_ON(len > MAX_PACKET_LEN); - - skb_trim(skb, len); + err = pskb_trim(skb, len); + if (err) { + pr_debug("%s: pskb_trim failed %i %d\n", dev->name, len, err); + dev->stats.rx_dropped++; + goto drop; + } + skb->truesize += skb->data_len; dev->stats.rx_bytes += skb->len; dev->stats.rx_packets++; @@ -161,7 +166,7 @@ static void try_fill_recv(struct virtnet_info *vi) { struct sk_buff *skb; struct scatterlist sg[2+MAX_SKB_FRAGS]; - int num, err; + int num, err, i; sg_init_table(sg, 2+MAX_SKB_FRAGS); for (;;) { @@ -171,6 +176,24 @@ static void try_fill_recv(struct virtnet_info *vi) skb_put(skb, MAX_PACKET_LEN); vnet_hdr_to_sg(sg, skb); + + if (vi->dev->features & NETIF_F_LRO) { + for (i = 0; i < MAX_SKB_FRAGS; i++) { + skb_frag_t *f = &skb_shinfo(skb)->frags[i]; + f->page = alloc_page(GFP_ATOMIC); + if (!f->page) + break; + + f->page_offset = 0; + f->size = PAGE_SIZE; + + skb->data_len += PAGE_SIZE; + skb->len += PAGE_SIZE; + + skb_shinfo(skb)->nr_frags++; + } + } + num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; skb_queue_head(&vi->recv, skb); @@ -466,6 +489,12 @@ static int virtnet_probe(struct virtio_device *vdev) dev->features |= NETIF_F_UFO; } + /* If we can receive ANY GSO packets, we must allocate large ones. */ + if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) + || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) + || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN)) + dev->features |= NETIF_F_LRO; + /* Configuration may specify what MAC to use. Otherwise random. */ if (virtio_has_feature(vdev, VIRTIO_NET_F_MAC)) { vdev->config->get(vdev, @@ -570,7 +599,9 @@ static struct virtio_device_id id_table[] = { static unsigned int features[] = { VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, - VIRTIO_NET_F_HOST_ECN, VIRTIO_F_NOTIFY_ON_EMPTY, + VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, + VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */ + VIRTIO_F_NOTIFY_ON_EMPTY, }; static struct virtio_driver virtio_net = { -- cgit v1.2.3 From 16fbfefacf569b165afe0f95b013ea1125865d03 Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Fri, 13 Jun 2008 14:27:34 +0100 Subject: virtio_net: Set VIRTIO_NET_F_GUEST_CSUM feature We can handle receiving partial csums, so set the appropriate feature bit. (Fixes virtio:net_allow_receiving_sg_packets.patch) Signed-off-by: Mark McLoughlin Signed-off-by: Rusty Russell --- drivers/net/virtio_net.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 851927f4bb69..49f033287d22 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -597,7 +597,8 @@ static struct virtio_device_id id_table[] = { }; static unsigned int features[] = { - VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, + VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM, + VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */ -- cgit v1.2.3 From 3acc4e1803e2244ecc527823f953e8936a239818 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Jun 2008 10:00:05 +1000 Subject: virtio:net-recycle-unused-pages If we hack the virtio_net driver to always allocate full-sized (64k+) skbuffs, the driver slows down (lguest numbers): Time to receive 1GB (small buffers): 10.85 seconds Time to receive 1GB (64k+ buffers): 24.75 seconds Of course, large buffers use up more space in the ring, so we increase that from 128 to 2048: Time to receive 1GB (64k+ buffers, 2k ring): 16.61 seconds If we recycle pages rather than using alloc_page/free_page: Time to receive 1GB (64k+ buffers, 2k ring, recycle pages): 10.81 seconds This demonstrates that with efficient allocation, we don't need to have a separate "small buffer" queue. Signed-off-by: Rusty Russell --- drivers/net/virtio_net.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 49f033287d22..bd67d915bad7 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -58,6 +58,9 @@ struct virtnet_info /* Receive & send queues. */ struct sk_buff_head recv; struct sk_buff_head send; + + /* Chain pages by the private ptr. */ + struct page *pages; }; static inline struct virtio_net_hdr *skb_vnet_hdr(struct sk_buff *skb) @@ -70,6 +73,23 @@ static inline void vnet_hdr_to_sg(struct scatterlist *sg, struct sk_buff *skb) sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr)); } +static void give_a_page(struct virtnet_info *vi, struct page *page) +{ + page->private = (unsigned long)vi->pages; + vi->pages = page; +} + +static struct page *get_a_page(struct virtnet_info *vi, gfp_t gfp_mask) +{ + struct page *p = vi->pages; + + if (p) + vi->pages = (struct page *)p->private; + else + p = alloc_page(gfp_mask); + return p; +} + static void skb_xmit_done(struct virtqueue *svq) { struct virtnet_info *vi = svq->vdev->priv; @@ -98,6 +118,15 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, } len -= sizeof(struct virtio_net_hdr); + if (len <= MAX_PACKET_LEN) { + unsigned int i; + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) + give_a_page(dev->priv, skb_shinfo(skb)->frags[i].page); + skb->data_len = 0; + skb_shinfo(skb)->nr_frags = 0; + } + err = pskb_trim(skb, len); if (err) { pr_debug("%s: pskb_trim failed %i %d\n", dev->name, len, err); @@ -180,7 +209,7 @@ static void try_fill_recv(struct virtnet_info *vi) if (vi->dev->features & NETIF_F_LRO) { for (i = 0; i < MAX_SKB_FRAGS; i++) { skb_frag_t *f = &skb_shinfo(skb)->frags[i]; - f->page = alloc_page(GFP_ATOMIC); + f->page = get_a_page(vi, GFP_ATOMIC); if (!f->page) break; @@ -509,6 +538,7 @@ static int virtnet_probe(struct virtio_device *vdev) vi->dev = dev; vi->vdev = vdev; vdev->priv = vi; + vi->pages = NULL; /* If they give us a callback when all buffers are done, we don't need * the timer. */ @@ -588,6 +618,10 @@ static void virtnet_remove(struct virtio_device *vdev) vdev->config->del_vq(vi->svq); vdev->config->del_vq(vi->rvq); unregister_netdev(vi->dev); + + while (vi->pages) + __free_pages(get_a_page(vi, GFP_KERNEL), 0); + free_netdev(vi->dev); } -- cgit v1.2.3 From ce43b09be5d17ab4c75f1b616e0df6b8551b8fbe Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Jun 2008 10:00:05 +1000 Subject: virtio:transport-features We assign feature bits as required, but it makes sense to reserve some for the particular transport, rather than the particular device. Signed-off-by: Rusty Russell --- drivers/virtio/virtio.c | 5 +++++ include/linux/virtio_config.h | 7 +++++++ 2 files changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index fc85cba64578..baf103361e3a 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c @@ -113,6 +113,11 @@ static int virtio_dev_probe(struct device *_d) set_bit(f, dev->features); } + /* Transport features are always preserved to pass to set_features. */ + for (i = VIRTIO_TRANSPORT_F_START; i < VIRTIO_TRANSPORT_F_END; i++) + if (device_features & (1 << i)) + set_bit(i, dev->features); + err = drv->probe(dev); if (err) add_status(dev, VIRTIO_CONFIG_S_FAILED); diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index f364bbf63c34..59a65e33cfa2 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h @@ -15,6 +15,13 @@ /* We've given up on this device. */ #define VIRTIO_CONFIG_S_FAILED 0x80 +/* Some virtio feature bits (currently bits 28 through 31) are reserved for the + * transport being used (eg. virtio_ring), the rest are per-device feature + * bits. */ +#define VIRTIO_TRANSPORT_F_START 28 +#define VIRTIO_TRANSPORT_F_END 32 +#define VIRTIO_TRANSPORT_F_MASK 0xF0000000 + /* Do we get callbacks when the ring is completely used, even if we've * suppressed them? */ #define VIRTIO_F_NOTIFY_ON_EMPTY 24 -- cgit v1.2.3 From c2842e2b9f481dc65467ea19569c9eaa7b3cd8ca Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Jun 2008 10:00:07 +1000 Subject: virtio:vring-enhance Generally, the other end of the virtio ring doesn't need to see where you're up to in consuming the ring. However, to completely understand what's going on from the outside, this information must be exposed. For example, if you want to save and restore a virtio_ring, but you're not the consumer because the kernel is using it directly. Fortunately, we have room to expand: the ring is always a whole number of pages and there's hundreds of bytes of padding after the avail ring and the used ring, whatever the number of descriptors (which must be a power of 2). We add a feature bit so the guest can tell the host that it's writing out the current value there, if it wants to use that. Signed-off-by: Rusty Russell --- drivers/lguest/lguest_device.c | 3 ++- drivers/virtio/virtio_pci.c | 6 +++++- drivers/virtio/virtio_ring.c | 28 ++++++++++++++++++++-------- include/linux/virtio_ring.h | 15 ++++++++++++++- 4 files changed, 41 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c index 1a8de57289eb..f292de2ad26e 100644 --- a/drivers/lguest/lguest_device.c +++ b/drivers/lguest/lguest_device.c @@ -95,7 +95,8 @@ static u32 lg_get_features(struct virtio_device *vdev) if (in_features[i / 8] & (1 << (i % 8))) features |= (1 << i); - return features; + /* Vring may want to play with the bits it's offered. */ + return vring_transport_features(features); } static void lg_set_features(struct virtio_device *vdev, u32 features) diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index eae7236310e4..e0e81e505658 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c @@ -88,10 +88,14 @@ static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev) static u32 vp_get_features(struct virtio_device *vdev) { struct virtio_pci_device *vp_dev = to_vp_device(vdev); + u32 features; /* When someone needs more than 32 feature bits, we'll need to * steal a bit to indicate that the rest are somewhere else. */ - return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); + features = ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); + + /* Vring may want to play with the bits it's offered. */ + return vring_transport_features(features); } /* virtio config->set_features() implementation */ diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 72bf8bc09014..49cb45c5b097 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -18,6 +18,7 @@ */ #include #include +#include #include #ifdef DEBUG @@ -52,9 +53,6 @@ struct vring_virtqueue /* Number we've added since last sync. */ unsigned int num_added; - /* Last used index we've seen. */ - u16 last_used_idx; - /* How to notify other side. FIXME: commonalize hcalls! */ void (*notify)(struct virtqueue *vq); @@ -173,12 +171,13 @@ static void detach_buf(struct vring_virtqueue *vq, unsigned int head) static inline bool more_used(const struct vring_virtqueue *vq) { - return vq->last_used_idx != vq->vring.used->idx; + return vring_last_used(&vq->vring) != vq->vring.used->idx; } static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len) { struct vring_virtqueue *vq = to_vvq(_vq); + struct vring_used_elem *u; void *ret; unsigned int i; @@ -195,8 +194,11 @@ static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len) return NULL; } - i = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].id; - *len = vq->vring.used->ring[vq->last_used_idx%vq->vring.num].len; + u = &vq->vring.used->ring[vring_last_used(&vq->vring) % vq->vring.num]; + i = u->id; + *len = u->len; + /* Make sure we don't reload i after doing checks. */ + rmb(); if (unlikely(i >= vq->vring.num)) { BAD_RING(vq, "id %u out of range\n", i); @@ -210,7 +212,7 @@ static void *vring_get_buf(struct virtqueue *_vq, unsigned int *len) /* detach_buf clears data, so grab it now. */ ret = vq->data[i]; detach_buf(vq, i); - vq->last_used_idx++; + vring_last_used(&vq->vring)++; END_USE(vq); return ret; } @@ -294,7 +296,6 @@ struct virtqueue *vring_new_virtqueue(unsigned int num, vq->vq.vq_ops = &vring_vq_ops; vq->notify = notify; vq->broken = false; - vq->last_used_idx = 0; vq->num_added = 0; #ifdef DEBUG vq->in_use = false; @@ -320,4 +321,15 @@ void vring_del_virtqueue(struct virtqueue *vq) } EXPORT_SYMBOL_GPL(vring_del_virtqueue); +/* Manipulates transport-specific feature bits. */ +u32 vring_transport_features(u32 features) +{ + u32 mask = ~VIRTIO_TRANSPORT_F_MASK; + + /* We let through any non-transport bits, and the only one we know. */ + mask &= ~(1 << VIRTIO_RING_F_PUBLISH_INDICES); + return features & mask; +} +EXPORT_SYMBOL_GPL(vring_transport_features); + MODULE_LICENSE("GPL"); diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h index abe481ed990e..65fae97ccc69 100644 --- a/include/linux/virtio_ring.h +++ b/include/linux/virtio_ring.h @@ -24,6 +24,9 @@ * optimization. */ #define VRING_AVAIL_F_NO_INTERRUPT 1 +/* We publish our last-seen used index at the end of the avail ring. */ +#define VIRTIO_RING_F_PUBLISH_INDICES 28 + /* Virtio ring descriptors: 16 bytes. These can chain together via "next". */ struct vring_desc { @@ -82,6 +85,7 @@ struct vring { * __u16 avail_flags; * __u16 avail_idx; * __u16 available[num]; + * __u16 last_used_idx; * * // Padding to the next page boundary. * char pad[]; @@ -90,6 +94,7 @@ struct vring { * __u16 used_flags; * __u16 used_idx; * struct vring_used_elem used[num]; + * __u16 last_avail_idx; * }; */ static inline void vring_init(struct vring *vr, unsigned int num, void *p, @@ -106,9 +111,14 @@ static inline unsigned vring_size(unsigned int num, unsigned long pagesize) { return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num) + pagesize - 1) & ~(pagesize - 1)) - + sizeof(__u16) * 2 + sizeof(struct vring_used_elem) * num; + + sizeof(__u16) * 2 + sizeof(struct vring_used_elem) * num + 2; } +/* We publish the last-seen used index at the end of the available ring, and + * vice-versa. These are at the end for backwards compatibility. */ +#define vring_last_used(vr) ((vr)->avail->ring[(vr)->num]) +#define vring_last_avail(vr) (*(__u16 *)&(vr)->used->ring[(vr)->num]) + #ifdef __KERNEL__ #include struct virtio_device; @@ -121,6 +131,9 @@ struct virtqueue *vring_new_virtqueue(unsigned int num, void (*callback)(struct virtqueue *vq)); void vring_del_virtqueue(struct virtqueue *vq); +/* Filter out unsupported transport-specific feature bits. */ +u32 vring_transport_features(u32 features); + irqreturn_t vring_interrupt(int irq, void *_vq); #endif /* __KERNEL__ */ #endif /* _LINUX_VIRTIO_RING_H */ -- cgit v1.2.3 From 82f2fd9464ee22a3abfc9c5e9157793bf7dfef2f Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Thu, 29 May 2008 11:08:26 +0200 Subject: virtio_blk: check for hardsector size from host Currently virtio_blk assumes a 512 byte hard sector size. This can cause trouble / performance issues if the backing has a different block size (like a file on an ext3 file system formatted with 4k block size or a dasd). Lets add a feature flag that tells the guest to use a different hard sector size than 512 byte. Signed-off-by: Christian Borntraeger Signed-off-by: Rusty Russell --- drivers/block/virtio_blk.c | 10 +++++++++- include/linux/virtio_blk.h | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index dd7ea203f940..42251095134f 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -196,6 +196,7 @@ static int virtblk_probe(struct virtio_device *vdev) int err; u64 cap; u32 v; + u32 blk_size; if (index_to_minor(index) >= 1 << MINORBITS) return -ENOSPC; @@ -290,6 +291,13 @@ static int virtblk_probe(struct virtio_device *vdev) if (!err) blk_queue_max_hw_segments(vblk->disk->queue, v); + /* Host can optionally specify the block size of the device */ + err = virtio_config_val(vdev, VIRTIO_BLK_F_BLK_SIZE, + offsetof(struct virtio_blk_config, blk_size), + &blk_size); + if (!err) + blk_queue_hardsect_size(vblk->disk->queue, blk_size); + add_disk(vblk->disk); return 0; @@ -330,7 +338,7 @@ static struct virtio_device_id id_table[] = { static unsigned int features[] = { VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, - VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, + VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, }; static struct virtio_driver virtio_blk = { diff --git a/include/linux/virtio_blk.h b/include/linux/virtio_blk.h index 5f79a5f9de79..52b593213f77 100644 --- a/include/linux/virtio_blk.h +++ b/include/linux/virtio_blk.h @@ -11,6 +11,7 @@ #define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */ #define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */ #define VIRTIO_BLK_F_RO 5 /* Disk is read-only */ +#define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available*/ struct virtio_blk_config { @@ -26,6 +27,8 @@ struct virtio_blk_config __u8 heads; __u8 sectors; } geometry; + /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */ + __u32 blk_size; } __attribute__((packed)); /* These two define direction. */ -- cgit v1.2.3 From 8325a3f6184e88ad398a5da420b573535566dd56 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Jun 2008 10:00:11 +1000 Subject: misc:down_nowait-drivers_char_snsc down_trylock -> down_try in drivers/char/snsc.c Signed-off-by: Rusty Russell --- drivers/char/snsc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c index 8fe099a41065..7688e15065b4 100644 --- a/drivers/char/snsc.c +++ b/drivers/char/snsc.c @@ -161,7 +161,7 @@ scdrv_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos) struct subch_data_s *sd = (struct subch_data_s *) file->private_data; /* try to get control of the read buffer */ - if (down_trylock(&sd->sd_rbs)) { + if (!down_try(&sd->sd_rbs)) { /* somebody else has it now; * if we're non-blocking, then exit... */ @@ -253,7 +253,7 @@ scdrv_write(struct file *file, const char __user *buf, struct subch_data_s *sd = (struct subch_data_s *) file->private_data; /* try to get control of the write buffer */ - if (down_trylock(&sd->sd_wbs)) { + if (!down_try(&sd->sd_wbs)) { /* somebody else has it now; * if we're non-blocking, then exit... */ -- cgit v1.2.3 From ccd6e8fe44ce1a5ddacc06ecb52bd6869e928e26 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Jun 2008 10:00:12 +1000 Subject: misc:down_nowait-drivers_char_viotape down_trylock -> down_try in drivers/char/viotape.c Signed-off-by: Rusty Russell --- drivers/char/viotape.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index c39ddaff5e8f..41d343a5f714 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -361,7 +361,7 @@ static ssize_t viotap_write(struct file *file, const char *buf, * semaphore */ if (noblock) { - if (down_trylock(&reqSem)) { + if (!down_try(&reqSem)) { ret = -EWOULDBLOCK; goto free_op; } @@ -451,7 +451,7 @@ static ssize_t viotap_read(struct file *file, char *buf, size_t count, * semaphore */ if (noblock) { - if (down_trylock(&reqSem)) { + if (!down_try(&reqSem)) { ret = -EWOULDBLOCK; goto free_op; } -- cgit v1.2.3 From d0414c5cb7b0a9e015428f116869fcd19de4394c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Jun 2008 10:00:12 +1000 Subject: misc:down_nowait-drivers_infiniband_core_user_mad down_trylock -> down_try in drivers/infiniband/core/user_mad.c Signed-off-by: Rusty Russell --- drivers/infiniband/core/user_mad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 840ede9ae965..a4517699569d 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -890,7 +890,7 @@ static int ib_umad_sm_open(struct inode *inode, struct file *filp) return -ENXIO; if (filp->f_flags & O_NONBLOCK) { - if (down_trylock(&port->sm_sem)) { + if (!down_try(&port->sm_sem)) { ret = -EAGAIN; goto fail; } -- cgit v1.2.3 From ee738f38baacfd4902174d372f7e21f4dd4c7862 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Jun 2008 10:00:12 +1000 Subject: misc:down_nowait-drivers_input_serio_hil_mlc down_trylock -> down_try in drivers/input/serio/hil_mlc.c Signed-off-by: Rusty Russell --- drivers/input/serio/hil_mlc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index 93a1a6ba216a..d1bb7f19d2a3 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c @@ -607,7 +607,7 @@ static inline void hilse_setup_input(hil_mlc *mlc, const struct hilse_node *node do_gettimeofday(&(mlc->instart)); mlc->icount = 15; memset(mlc->ipacket, 0, 16 * sizeof(hil_packet)); - BUG_ON(down_trylock(&mlc->isem)); + BUG_ON(!down_try(&mlc->isem)); } #ifdef HIL_MLC_DEBUG @@ -694,7 +694,7 @@ static int hilse_donode(hil_mlc *mlc) out2: write_unlock_irqrestore(&mlc->lock, flags); - if (down_trylock(&mlc->osem)) { + if (!down_try(&mlc->osem)) { nextidx = HILSEN_DOZE; break; } -- cgit v1.2.3 From 54edf7ed4c9c1834ac13cd2b839844ab37c083b2 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Jun 2008 10:00:12 +1000 Subject: misc:down_nowait-drivers_input_serio_hp_sdc_mlc down_trylock -> down_try in drivers/input/serio/hp_sdc_mlc.c Signed-off-by: Rusty Russell --- drivers/input/serio/hp_sdc_mlc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/input/serio/hp_sdc_mlc.c b/drivers/input/serio/hp_sdc_mlc.c index 587398f5c9df..8f532bb4f3ec 100644 --- a/drivers/input/serio/hp_sdc_mlc.c +++ b/drivers/input/serio/hp_sdc_mlc.c @@ -148,7 +148,7 @@ static int hp_sdc_mlc_in(hil_mlc *mlc, suseconds_t timeout) priv = mlc->priv; /* Try to down the semaphore */ - if (down_trylock(&mlc->isem)) { + if (!down_try(&mlc->isem)) { struct timeval tv; if (priv->emtestmode) { mlc->ipacket[0] = @@ -186,13 +186,13 @@ static int hp_sdc_mlc_cts(hil_mlc *mlc) priv = mlc->priv; /* Try to down the semaphores -- they should be up. */ - BUG_ON(down_trylock(&mlc->isem)); - BUG_ON(down_trylock(&mlc->osem)); + BUG_ON(!down_try(&mlc->isem)); + BUG_ON(!down_try(&mlc->osem)); up(&mlc->isem); up(&mlc->osem); - if (down_trylock(&mlc->csem)) { + if (!down_try(&mlc->csem)) { if (priv->trans.act.semaphore != &mlc->csem) goto poll; else @@ -229,7 +229,7 @@ static void hp_sdc_mlc_out(hil_mlc *mlc) priv = mlc->priv; /* Try to down the semaphore -- it should be up. */ - BUG_ON(down_trylock(&mlc->osem)); + BUG_ON(!down_try(&mlc->osem)); if (mlc->opacket & HIL_DO_ALTER_CTRL) goto do_control; @@ -240,7 +240,7 @@ static void hp_sdc_mlc_out(hil_mlc *mlc) return; } /* Shouldn't be sending commands when loop may be busy */ - BUG_ON(down_trylock(&mlc->csem)); + BUG_ON(!down_try(&mlc->csem)); up(&mlc->csem); priv->trans.actidx = 0; @@ -296,7 +296,7 @@ static void hp_sdc_mlc_out(hil_mlc *mlc) priv->tseq[3] = 0; if (mlc->opacket & HIL_CTRL_APE) { priv->tseq[3] |= HP_SDC_LPC_APE_IPF; - down_trylock(&mlc->csem); + down_try(&mlc->csem); } enqueue: hp_sdc_enqueue_transaction(&priv->trans); -- cgit v1.2.3 From 973c558760f455abbd8a0788082273bf4d2b128e Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Jun 2008 10:00:12 +1000 Subject: misc:down_nowait-drivers_md_dm-raid1 down_trylock -> down_try in drivers/md/dm-raid1.c Signed-off-by: Rusty Russell --- drivers/md/dm-raid1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index ff05fe893083..137f0241aed0 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -587,7 +587,7 @@ static void rh_recovery_prepare(struct region_hash *rh) /* Extra reference to avoid race with rh_stop_recovery */ atomic_inc(&rh->recovery_in_flight); - while (!down_trylock(&rh->recovery_count)) { + while (down_try(&rh->recovery_count)) { atomic_inc(&rh->recovery_in_flight); if (__rh_recovery_prepare(rh) <= 0) { atomic_dec(&rh->recovery_in_flight); -- cgit v1.2.3 From 40be4bbf7425593fbe1293c88949265a96d1d2de Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Jun 2008 10:00:13 +1000 Subject: misc:down_nowait-drivers_net_3c527 down_trylock -> down_try in drivers/net/3c527.c Signed-off-by: Rusty Russell --- drivers/net/3c527.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c index fae295b6809c..024b8678d2af 100644 --- a/drivers/net/3c527.c +++ b/drivers/net/3c527.c @@ -577,7 +577,7 @@ static int mc32_command_nowait(struct net_device *dev, u16 cmd, void *data, int int ioaddr = dev->base_addr; int ret = -1; - if (down_trylock(&lp->cmd_mutex) == 0) + if (down_try(&lp->cmd_mutex)) { lp->cmd_nonblocking=1; lp->exec_box->mbox=0; -- cgit v1.2.3 From 1d81e47f6eb678dffa7525a4143d8fb73de6429c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Jun 2008 10:00:13 +1000 Subject: misc:down_nowait-drivers_net_irda_sir_dev down_trylock -> down_try in drivers/net/irda/sir_dev.c Signed-off-by: Rusty Russell --- drivers/net/irda/sir_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index 6078e03de9a8..894aade319b6 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c @@ -286,7 +286,7 @@ int sirdev_schedule_request(struct sir_dev *dev, int initial_state, unsigned par IRDA_DEBUG(2, "%s - state=0x%04x / param=%u\n", __FUNCTION__, initial_state, param); - if (down_trylock(&fsm->sem)) { + if (!down_try(&fsm->sem)) { if (in_interrupt() || in_atomic() || irqs_disabled()) { IRDA_DEBUG(1, "%s(), state machine busy!\n", __FUNCTION__); return -EWOULDBLOCK; -- cgit v1.2.3 From 235ff103cfd701447445208290df7bed464e52fe Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Jun 2008 10:00:13 +1000 Subject: misc:down_nowait-drivers_net_wireless_airo down_trylock -> down_try in drivers/net/wireless/airo.c Signed-off-by: Rusty Russell --- drivers/net/wireless/airo.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 32019fb878d8..adcc2187b424 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -2138,7 +2138,7 @@ static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) { fids[i] |= (len << 16); priv->xmit.skb = skb; priv->xmit.fid = i; - if (down_trylock(&priv->sem) != 0) { + if (!down_try(&priv->sem)) { set_bit(FLAG_PENDING_XMIT, &priv->flags); netif_stop_queue(dev); set_bit(JOB_XMIT, &priv->jobs); @@ -2209,7 +2209,7 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) { fids[i] |= (len << 16); priv->xmit11.skb = skb; priv->xmit11.fid = i; - if (down_trylock(&priv->sem) != 0) { + if (!down_try(&priv->sem)) { set_bit(FLAG_PENDING_XMIT11, &priv->flags); netif_stop_queue(dev); set_bit(JOB_XMIT11, &priv->jobs); @@ -2257,7 +2257,7 @@ static struct net_device_stats *airo_get_stats(struct net_device *dev) if (!test_bit(JOB_STATS, &local->jobs)) { /* Get stats out of the card if available */ - if (down_trylock(&local->sem) != 0) { + if (!down_try(&local->sem)) { set_bit(JOB_STATS, &local->jobs); wake_up_interruptible(&local->thr_wait); } else @@ -2284,7 +2284,7 @@ static void airo_set_multicast_list(struct net_device *dev) { if ((dev->flags ^ ai->flags) & IFF_PROMISC) { change_bit(FLAG_PROMISC, &ai->flags); - if (down_trylock(&ai->sem) != 0) { + if (!down_try(&ai->sem)) { set_bit(JOB_PROMISC, &ai->jobs); wake_up_interruptible(&ai->thr_wait); } else @@ -3212,7 +3212,7 @@ static irqreturn_t airo_interrupt(int irq, void *dev_id) set_bit(FLAG_UPDATE_UNI, &apriv->flags); set_bit(FLAG_UPDATE_MULTI, &apriv->flags); - if (down_trylock(&apriv->sem) != 0) { + if (!down_try(&apriv->sem)) { set_bit(JOB_EVENT, &apriv->jobs); wake_up_interruptible(&apriv->thr_wait); } else @@ -7659,7 +7659,7 @@ static struct iw_statistics *airo_get_wireless_stats(struct net_device *dev) if (!test_bit(JOB_WSTATS, &local->jobs)) { /* Get stats out of the card if available */ - if (down_trylock(&local->sem) != 0) { + if (!down_try(&local->sem)) { set_bit(JOB_WSTATS, &local->jobs); wake_up_interruptible(&local->thr_wait); } else -- cgit v1.2.3 From eebbea7d4186346aee759d393b403122b3318503 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Jun 2008 10:00:13 +1000 Subject: misc:down_nowait-drivers_scsi_aacraid_commsup down_trylock -> down_try in drivers/scsi/aacraid/commsup.c Signed-off-by: Rusty Russell --- drivers/scsi/aacraid/commsup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 289304aab690..c011d05caaa6 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -490,7 +490,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, * hardware failure has occurred. */ unsigned long count = 36000000L; /* 3 minutes */ - while (down_trylock(&fibptr->event_wait)) { + while (!down_try(&fibptr->event_wait)) { int blink; if (--count == 0) { struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue]; -- cgit v1.2.3 From a67a6f5dda6ed76c42d745628d3868cd504ebd73 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Jun 2008 10:00:14 +1000 Subject: misc:down_nowait-drivers_usb_core_usb down_trylock -> down_try for usb_trylock_device() I took the liberty of reversing the sense of usb_trylock_device(): it only has one user anyway. Signed-off-by: Rusty Russell --- drivers/usb/core/usb.c | 2 +- include/linux/usb.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 325774375837..2f76846e1c60 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -478,7 +478,7 @@ int usb_lock_device_for_reset(struct usb_device *udev, } } - while (usb_trylock_device(udev) != 0) { + while (!usb_trylock_device(udev)) { /* If we can't acquire the lock after waiting one second, * we're probably deadlocked */ diff --git a/include/linux/usb.h b/include/linux/usb.h index c08689ea9b4b..ea2c2ecafb8d 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -491,7 +491,7 @@ extern void usb_put_dev(struct usb_device *dev); /* USB device locking */ #define usb_lock_device(udev) down(&(udev)->dev.sem) #define usb_unlock_device(udev) up(&(udev)->dev.sem) -#define usb_trylock_device(udev) down_trylock(&(udev)->dev.sem) +#define usb_trylock_device(udev) down_try(&(udev)->dev.sem) extern int usb_lock_device_for_reset(struct usb_device *udev, const struct usb_interface *iface); -- cgit v1.2.3 From f19305002b9c5d14db22ae28025e948dd6511a31 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 16 Jun 2008 10:00:14 +1000 Subject: misc:down_nowait-drivers_usb_gadget_inode down_trylock -> down_try in drivers/usb/gadget/inode.c Signed-off-by: Rusty Russell --- drivers/usb/gadget/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 69b0a2754f2a..942c60de9f10 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -298,7 +298,7 @@ get_ready_ep (unsigned f_flags, struct ep_data *epdata) int val; if (f_flags & O_NONBLOCK) { - if (down_trylock (&epdata->lock) != 0) + if (!down_try (&epdata->lock)) goto nonblock; if (epdata->state != STATE_EP_ENABLED) { up (&epdata->lock); -- cgit v1.2.3