aoe: various enhancements and cleanup from v50 to v60
Subsystems (2)
cover aoe: various enhancements and cleanup from v50 to v60
This patch series is based on linux-next/akpm from 11 Oct.
The patch that modifies aoenet.c:tx to print a warning does not affect locking but nonetheless causes a new sparse context warning to appear. Before a bug in sparse suppressed the warning. We will soon be able to use the new __must_hold() macro that now appears only in (not linux-next/akpm but) mm, making the warning go away by telling sparse that the tx function enters and exits with a lock held.
Ed L. Cashin (9):
aoe: describe the behavior of the "err" character device
aoe: print warning regarding a common reason for dropped transmits
aoe: update cap on outstanding commands based on config query
response
aoe: support the forgetting (flushing) of a user-specified AoE target
aoe: support larger I/O requests via aoe_maxsectors module param
aoe: "payload" sysfs file exports per-AoE-command data transfer size
aoe: cleanup: remove unused ata_scnt function
aoe: whitespace cleanup
aoe: update driver-internal version number to 60
drivers/block/aoe/aoe.h | 10 ++++---- drivers/block/aoe/aoeblk.c | 19 ++++++++++++++++++ drivers/block/aoe/aoechr.c | 7 +++++- drivers/block/aoe/aoecmd.c | 22 +++++++------------- drivers/block/aoe/aoedev.c | 44 +++++++++++++++++++++++++++++++++++++----- drivers/block/aoe/aoemain.c | 2 +- drivers/block/aoe/aoenet.c | 15 ++++++++++--- 7 files changed, 88 insertions(+), 31 deletions(-)
PATCH 1/9 aoe: describe the behavior of the "err" character device
--- drivers/block/aoe/aoechr.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
drivers/block/aoe/aoechr.c +5 -0
@@ -39,6 +39,11 @@ struct ErrMsg { };static DEFINE_MUTEX (aoechr_mutex); + +/* A ring buffer of error messages, to be read through +* "/dev/etherd/err". When no messages are present, +* readers will block waiting for messages to appear. +*/ static struct ErrMsg emsgs[NMSG ];static int emsgs_head_idx, emsgs_tail_idx;static struct completion emsgs_comp;
Signature · 1 line
1.7.1
PATCH 2/9 aoe: print warning regarding a common reason for dropped transmits
In reply to Ed CashinDropped transmits are not common, but when they do occur, increasing the transmit queue length often helps.
--- drivers/block/aoe/aoenet.c | 11 +++++++++-- 1 files changed, 9 insertions(+), 2 deletions(-)
drivers/block/aoe/aoenet.c +9 -2
@@ -50,7 +50,11 @@ __setup("aoe_iflist=", aoe_iflist_setup);static spinlock_t txlock;static struct sk_buff_head skbtxq; -/* enters with txlock held */ +/* enters with txlock held +* +* Use __must_hold(&txlock) for sparse when upcoming patch adds it to +* compiler.h. +*/ static int tx (void ) {
@@ -58,7 +62,10 @@ tx(void)while ((skb =skb_dequeue (&skbtxq))) {spin_unlock_irq (&txlock); -dev_queue_xmit (skb); +if (dev_queue_xmit (skb) ==NET_XMIT_DROP &&net_ratelimit ()) +pr_warn ("aoe: packet could not be sent on %s. %s\n" , + skb->dev ? skb->dev->name :"netif" , +"consider increasing tx_queue_len" );spin_lock_irq (&txlock); }return 0 ;
Signature · 1 line
1.7.1
Re: [PATCH 2/9] aoe: print warning regarding a common reason for dropped transmits
Quoted 10 lines · On Mon, 15 Oct 2012 18:42:43 -0700 Ed Cashin <[email protected]> wrote:
Dropped transmits are not common, but when they do occur, increasing the transmit queue length often helps.
...
+/* enters with txlock held
+ *
+ * Use__must_hold(&txlock)for sparse when upcoming patch adds it to
+ *compiler.h.
+ */
Let's just make that change now and I'll take care of getting linux-compilerh-add-__must_hold-macro-for-functions-called-with-a-lock-held.patch merged ahead of this one.
PATCH 3/9 aoe: update cap on outstanding commands based on config query response
In reply to Ed CashinThe ATA over Ethernet config query response contains a "buffer count" field reflecting the AoE target's capacity to buffer incoming AoE commands.
By taking the current value of this field into accound, we increase performance throughput or avoid network congestion, when the value has increased or decreased, respectively.
--- drivers/block/aoe/aoe.h | 6 +++--- drivers/block/aoe/aoecmd.c | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-)
drivers/block/aoe/aoe.h +3 -3
@@ -122,14 +122,14 @@ struct aoeif {struct aoetgt {unsigned char addr[6 ]; -ushort nframes; +ushort nframes;/* cap on frames to use */ struct aoedev *d;/* parent device I belong to */ struct list_head ffree;/* list of free frames */ struct aoeif ifs[NAOEIFS ];struct aoeif *ifp;/* current aoeif in use */ ushort nout; -ushort maxout; -ulong falloc; +ushort maxout;/* current value for max outstanding */ +ulong falloc;/* number of allocated frames */ ulong lastwadj;/* last window adjustment */ int minbcnt;int wpkts, rpkts;
drivers/block/aoe/aoecmd.c +5 -1
@@ -1373,7 +1373,11 @@ aoecmd_cfg_rsp(struct sk_buff *skb)spin_lock_irqsave (&d->lock, flags); t =gettgt (d, h->src); -if (!t) { +if (t) { + t->nframes = n; +if (n < t->maxout) + t->maxout = n; + }else { t =addtgt (d, h->src, n);if (!t) goto bail;
Signature · 1 line
1.7.1
PATCH 4/9 aoe: support the forgetting (flushing) of a user-specified AoE target
In reply to Ed CashinUsers sometimes want to cause the aoe driver to forget a particular previously discovered device when it is no longer online. The aoetools provide an "aoe-flush" command that users run to perform this administrative task. The changes below provide the support needed in the driver.
--- drivers/block/aoe/aoedev.c | 44 ++++++++++++++++++++++++++++++++++++++------ 1 files changed, 38 insertions(+), 6 deletions(-)
drivers/block/aoe/aoedev.c +38 -6
@@ -241,6 +241,30 @@ aoedev_freedev(struct aoedev *d)kfree (d); } +/* return whether the user asked for this particular +* device to be flushed +*/ +static int +user_req (char *s,size_t slen,struct aoedev *d) +{ +char *p; +size_t lim; + +if (!d->gd) +return 0 ; + p =strrchr (d->gd->disk_name,'/' ); +if (!p) + p = d->gd->disk_name; +else + p +=1 ; + lim =sizeof (d->gd->disk_name); + lim -= p - d->gd->disk_name; +if (slen < lim) + lim = slen; + +return !strncmp (s, p, lim); +} +int aoedev_flush (const char __user *str,size_t cnt) {
@@ -249,6 +273,7 @@ aoedev_flush(const char __user *str, size_t cnt)struct aoedev *rmd =NULL ;char buf[16 ];int all =0 ; +int specified =0 ;/* flush a specific device */ if (cnt >=3 ) {if (cnt >sizeof buf)
@@ -256,26 +281,33 @@ aoedev_flush(const char __user *str, size_t cnt)if (copy_from_user (buf, str, cnt))return -EFAULT ; all = !strncmp (buf,"all" ,3 ); +if (!all) + specified =1 ; }spin_lock_irqsave (&devlist_lock, flags); dd = &devlist;while ((d = *dd)) {spin_lock (&d->lock); -if ((!all && (d->flags &DEVFL_UP )) +if (specified) { +if (!user_req (buf, cnt, d)) + goto skip; + }else if ((!all && (d->flags &DEVFL_UP )) || (d->flags & (DEVFL_GDALLOC |DEVFL_NEWSIZE )) || d->nopen - || d->ref) { -spin_unlock (&d->lock); - dd = &d->next; -continue ; - } + || d->ref) + goto skip; + *dd = d->next;aoedev_downdev (d); d->flags |=DEVFL_TKILL ;spin_unlock (&d->lock); d->next = rmd; rmd = d; +continue ; +skip: +spin_unlock (&d->lock); + dd = &d->next; }spin_unlock_irqrestore (&devlist_lock, flags);while ((d = rmd)) {
Signature · 1 line
1.7.1
PATCH 5/9 aoe: support larger I/O requests via aoe_maxsectors module param
In reply to Ed CashinThe GPFS filesystem is an example of an aoe user that requires the aoe driver to support I/O request sizes larger than the default. Most users will not need large I/O request sizes, because they would need to be split up into multiple AoE commands anyway.
--- drivers/block/aoe/aoeblk.c | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-)
drivers/block/aoe/aoeblk.c +9 -0
@@ -16,11 +16,18 @@#include <linux/netdevice.h> #include <linux/mutex.h> #include <linux/export.h> +#include <linux/moduleparam.h> #include "aoe.h" static DEFINE_MUTEX (aoeblk_mutex);static struct kmem_cache *buf_pool_cache; +/* GPFS needs a larger value than the default. */ +static int aoe_maxsectors; +module_param (aoe_maxsectors, int,0644 ); +MODULE_PARM_DESC (aoe_maxsectors, +"When nonzero, set the maximum number of sectors per I/O request" ); +static ssize_t aoedisk_show_state (struct device *dev,struct device_attribute *attr,char *page) {
@@ -248,6 +255,8 @@ aoeblk_gdalloc(void *vp) d->blkq = gd->queue = q; q->queuedata = d; d->gd = gd; +if (aoe_maxsectors) +blk_queue_max_hw_sectors (q, aoe_maxsectors); gd->major =AOE_MAJOR ; gd->first_minor = d->sysminor; gd->fops = &aoe_bdops;
Signature · 1 line
1.7.1
PATCH 6/9 aoe: "payload" sysfs file exports per-AoE-command data transfer size
In reply to Ed CashinThe userland aoetools package includes an "aoe-stat" command that can display a "payload size" column when the aoe driver exports this information. Users can quickly see what amount of user data is transferred inside each AoE command on the network, network headers excluded.
--- drivers/block/aoe/aoeblk.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-)
drivers/block/aoe/aoeblk.c +10 -0
@@ -98,6 +98,14 @@ static ssize_t aoedisk_show_fwver(struct device *dev,return snprintf (page,PAGE_SIZE ,"0x%04x\n" , (unsigned int ) d->fw_ver); } +static ssize_t aoedisk_show_payload (struct device *dev, +struct device_attribute *attr,char *page) +{ +struct gendisk *disk =dev_to_disk (dev); +struct aoedev *d = disk->private_data; + +return snprintf (page,PAGE_SIZE ,"%lu\n" , d->maxbcnt); +} static DEVICE_ATTR(state, S_IRUGO, aoedisk_show_state, NULL); static DEVICE_ATTR(mac, S_IRUGO, aoedisk_show_mac, NULL);
@@ -106,12 +114,14 @@ static struct device_attribute dev_attr_firmware_version = { .attr = { .name = "firmware-version", .mode = S_IRUGO }, .show = aoedisk_show_fwver, }; +static DEVICE_ATTR(payload, S_IRUGO, aoedisk_show_payload, NULL);static struct attribute *aoe_attrs[] = { &dev_attr_state.attr, &dev_attr_mac.attr, &dev_attr_netif.attr, &dev_attr_firmware_version.attr, + &dev_attr_payload.attr,NULL , };
Signature · 1 line
1.7.1
PATCH 7/9 aoe: cleanup: remove unused ata_scnt function
In reply to Ed Cashin--- drivers/block/aoe/aoecmd.c | 10 ---------- 1 files changed, 0 insertions(+), 10 deletions(-)
drivers/block/aoe/aoecmd.c +0 -10
@@ -552,16 +552,6 @@ sthtith(struct aoedev *d)return 1 ; } -static inline unsigned char -ata_scnt (unsigned char *packet) { -struct aoe_hdr *h; -struct aoe_atahdr *ah; - - h = (struct aoe_hdr *) packet; - ah = (struct aoe_atahdr *) (h+1 ); -return ah->scnt; -} -static void rexmit_timer (ulong vp) {
Signature · 1 line
1.7.1
PATCH 8/9 aoe: whitespace cleanup
In reply to Ed Cashin--- drivers/block/aoe/aoe.h | 2 +- drivers/block/aoe/aoechr.c | 2 +- drivers/block/aoe/aoecmd.c | 6 +++--- drivers/block/aoe/aoemain.c | 2 +- drivers/block/aoe/aoenet.c | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-)
drivers/block/aoe/aoe.h +1 -1
@@ -151,7 +151,7 @@ struct aoedev {struct work_struct work;/* disk create work struct */ struct gendisk *gd;struct request_queue *blkq; -struct hd_geometry geo; +struct hd_geometry geo;sector_t ssize;struct timer_list timer;spinlock_t lock;
drivers/block/aoe/aoechr.c +1 -1
@@ -287,7 +287,7 @@ aoechr_init(void)int n, i; n =register_chrdev (AOE_MAJOR ,"aoechr" , &aoe_fops); -if (n <0 ) { +if (n <0 ) {printk (KERN_ERR "aoe: can't register char device\n" );return n; }
drivers/block/aoe/aoecmd.c +3 -3
@@ -978,7 +978,7 @@ ktiocomplete(struct frame *f)pr_err ("aoe: ata error cmd=%2.2Xh stat=%2.2Xh from e%ld.%d\n" , ahout->cmdstat, ahin->cmdstat, d->aoemajor, d->aoeminor); -noskb:if (buf) +noskb:if (buf)clear_bit (BIO_UPTODATE , &buf->bio->bi_flags); goto badrsp; }
@@ -1191,7 +1191,7 @@ aoecmd_cfg(ushort aoemajor, unsigned char aoeminor)aoecmd_cfg_pkts (aoemajor, aoeminor, &queue);aoenet_xmit (&queue); } - +struct sk_buff *aoecmd_ata_id (struct aoedev *d) {
@@ -1230,7 +1230,7 @@ aoecmd_ata_id(struct aoedev *d)return skb_clone (skb,GFP_ATOMIC ); } - +static struct aoetgt *addtgt (struct aoedev *d,char *addr,ulong nframes) {
drivers/block/aoe/aoemain.c +1 -1
@@ -105,7 +105,7 @@ aoe_init(void)aoechr_exit (); chr_fail:aoedev_exit (); - +printk (KERN_INFO "aoe: initialisation failure.\n" );return ret; }
drivers/block/aoe/aoenet.c +2 -2
@@ -126,8 +126,8 @@ aoenet_xmit(struct sk_buff_head *queue) } } -/* -* (1) len doesn't include the header by default. I want this. +/* +* (1) len doesn't include the header by default. I want this. */ static int aoenet_rcv (struct sk_buff *skb,struct net_device *ifp,struct packet_type *pt,struct net_device *orig_dev)
Signature · 1 line
1.7.1
PATCH 9/9 aoe: update driver-internal version number to 60
In reply to Ed Cashin--- drivers/block/aoe/aoe.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/block/aoe/aoe.h +1 -1
@@ -1,5 +1,5 @@/* Copyright (c) 2012 Coraid, Inc. See COPYING for GPL terms. */ -#define VERSION "50" +#define VERSION "60"#define AOE_MAJOR 152#define DEVICE_NAME "aoe"
Signature · 1 line
1.7.1