Re: [PATCH 1/7] aoe: support more AoE addresses with dynamic block device minor numbers

2012-10-02 Thread Ed Cashin
On Oct 2, 2012, at 5:12 PM, Andrew Morton wrote:
...
>> +static int
>> +minor_get(ulong *minor)
>> {
>> -struct aoedev *d;
>>  ulong flags;
>> +ulong n;
>> +int error = 0;
>> +
>> +spin_lock_irqsave(_minors_lock, flags);
>> +n = find_first_zero_bit(used_minors, N_DEVS);
>> +if (n < N_DEVS)
>> +set_bit(n, used_minors);
>> +else
>> +error = -1;
>> +spin_unlock_irqrestore(_minors_lock, flags);
>> +
>> +*minor = n * AOE_PARTITIONS;
>> +return error;
>> +}
> 
> - can use the more efficient __set_bit() inside that spinlock.

Thanks for that observation.  Because this operation occurs on target 
discovery, which is expected to be relatively infrequent, my inclination is to 
leave it in its atomic form, though, and leave the __set_bit() for another time 
when optimization is needed.  Like you said, this is a minor point.  I wouldn't 
mind changing it, though, if you think it's worth me resubmitting the patch.  
Just let me know.

> - could avoid setting *minor if we're returning an error.

Yes.  The only caller of aoedev.c:minor_get() handles that correctly.  Again, 
just let me know if you think this is worth a resubmission of the patch.  
Otherwise I'll just make a note to myself to try to avoid setting output 
parameters on error in the future.

-- 
  Ed Cashin
  ecas...@coraid.com


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/7] aoe: support more AoE addresses with dynamic block device minor numbers

2012-10-02 Thread Andrew Morton
On Mon, 1 Oct 2012 18:59:12 -0700
Ed Cashin  wrote:

> The ATA over Ethernet protocol uses a major (shelf) and
> minor (slot) address to identify a particular storage target.
> These changes remove an artificial limitation the aoe driver
> imposes on the use of AoE addresses.  For example, without these
> changes, the slot address has a maximum of 15, but users commonly
> use slot numbers much greater than that.
> 
> The AoE shelf and slot address space is often used sparsely.
> Instead of using a static mapping between AoE addresses and the
> block device minor number, the block device minor numbers are now
> allocated on demand.
> 
> ...

Very minor things...

>
> ...
>
> +static int
> +minor_get(ulong *minor)
>  {
> - struct aoedev *d;
>   ulong flags;
> + ulong n;
> + int error = 0;
> +
> + spin_lock_irqsave(_minors_lock, flags);
> + n = find_first_zero_bit(used_minors, N_DEVS);
> + if (n < N_DEVS)
> + set_bit(n, used_minors);
> + else
> + error = -1;
> + spin_unlock_irqrestore(_minors_lock, flags);
> +
> + *minor = n * AOE_PARTITIONS;
> + return error;
> +}

- can use the more efficient __set_bit() inside that spinlock.

- could avoid setting *minor if we're returning an error.

> - spin_lock_irqsave(_lock, flags);
> +static void
> +minor_free(ulong minor)
> +{
> + ulong flags;
>  
> - for (d=devlist; d; d=d->next)
> - if (d->aoemajor == maj && d->aoeminor == min) {
> - d->ref++;
> - break;
> - }
> + minor /= AOE_PARTITIONS;
> + BUG_ON(minor >= N_DEVS);
>  
> - spin_unlock_irqrestore(_lock, flags);
> - return d;
> + spin_lock_irqsave(_minors_lock, flags);
> + BUG_ON(!test_bit(minor, used_minors));
> + clear_bit(minor, used_minors);
> + spin_unlock_irqrestore(_minors_lock, flags);
>  }

Could use

BUG_ON(!__test_and_clear_bit(...));

This will work, but I think it's bad form to put an expression with
side-effects inside an assert macro.


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/7] aoe: support more AoE addresses with dynamic block device minor numbers

2012-10-02 Thread Ed Cashin
I should have mentioned that these seven patches were made for linux-next/akpm, 
which contains the last 14-patch series for aoe.

On Oct 1, 2012, at 9:59 PM, "Ed Cashin"  wrote:

> The ATA over Ethernet protocol uses a major (shelf) and
> minor (slot) address to identify a particular storage target.
> These changes remove an artificial limitation the aoe driver
> imposes on the use of AoE addresses.  For example, without these
> changes, the slot address has a maximum of 15, but users commonly
> use slot numbers much greater than that.
> 
> The AoE shelf and slot address space is often used sparsely.
> Instead of using a static mapping between AoE addresses and the
> block device minor number, the block device minor numbers are now
> allocated on demand.
> 
> Signed-off-by: Ed Cashin 
> ---
> drivers/block/aoe/aoe.h|6 ++--
> drivers/block/aoe/aoeblk.c |2 +-
> drivers/block/aoe/aoechr.c |2 +-
> drivers/block/aoe/aoecmd.c |   25 -
> drivers/block/aoe/aoedev.c |   86 ++--
> 5 files changed, 72 insertions(+), 49 deletions(-)
> 
> diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
> index 27d0a21..7b694f7 100644
> --- a/drivers/block/aoe/aoe.h
> +++ b/drivers/block/aoe/aoe.h
> @@ -49,6 +49,8 @@ struct aoe_hdr {
>__be32 tag;
> };
> 
> +#define AOE_MAXSHELF (0x-1)/* one less than the broadcast shelf 
> address */
> +
> struct aoe_atahdr {
>unsigned char aflags;
>unsigned char errfeat;
> @@ -211,8 +213,7 @@ void aoe_ktstop(struct ktstate *k);
> 
> int aoedev_init(void);
> void aoedev_exit(void);
> -struct aoedev *aoedev_by_aoeaddr(int maj, int min);
> -struct aoedev *aoedev_by_sysminor_m(ulong sysminor);
> +struct aoedev *aoedev_by_aoeaddr(ulong maj, int min, int do_alloc);
> void aoedev_downdev(struct aoedev *d);
> int aoedev_flush(const char __user *str, size_t size);
> void aoe_failbuf(struct aoedev *, struct buf *);
> @@ -223,4 +224,3 @@ void aoenet_exit(void);
> void aoenet_xmit(struct sk_buff_head *);
> int is_aoe_netif(struct net_device *ifp);
> int set_aoe_iflist(const char __user *str, size_t size);
> -
> diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
> index 83160ab..00dfc50 100644
> --- a/drivers/block/aoe/aoeblk.c
> +++ b/drivers/block/aoe/aoeblk.c
> @@ -249,7 +249,7 @@ aoeblk_gdalloc(void *vp)
>q->queuedata = d;
>d->gd = gd;
>gd->major = AOE_MAJOR;
> -gd->first_minor = d->sysminor * AOE_PARTITIONS;
> +gd->first_minor = d->sysminor;
>gd->fops = _bdops;
>gd->private_data = d;
>set_capacity(gd, d->ssize);
> diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
> index deb30c1..ed57a89 100644
> --- a/drivers/block/aoe/aoechr.c
> +++ b/drivers/block/aoe/aoechr.c
> @@ -91,7 +91,7 @@ revalidate(const char __user *str, size_t size)
>pr_err("aoe: invalid device specification %s\n", buf);
>return -EINVAL;
>}
> -d = aoedev_by_aoeaddr(major, minor);
> +d = aoedev_by_aoeaddr(major, minor, 0);
>if (!d)
>return -EINVAL;
>spin_lock_irqsave(>lock, flags);
> diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
> index 39dacdb..94e810c 100644
> --- a/drivers/block/aoe/aoecmd.c
> +++ b/drivers/block/aoe/aoecmd.c
> @@ -1149,7 +1149,7 @@ aoecmd_ata_rsp(struct sk_buff *skb)
> 
>h = (struct aoe_hdr *) skb->data;
>aoemajor = be16_to_cpu(get_unaligned(>major));
> -d = aoedev_by_aoeaddr(aoemajor, h->minor);
> +d = aoedev_by_aoeaddr(aoemajor, h->minor, 0);
>if (d == NULL) {
>snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response "
>"for unknown device %d.%d\n",
> @@ -1330,7 +1330,7 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
>struct aoe_hdr *h;
>struct aoe_cfghdr *ch;
>struct aoetgt *t;
> -ulong flags, sysminor, aoemajor;
> +ulong flags, aoemajor;
>struct sk_buff *sl;
>struct sk_buff_head queue;
>u16 n;
> @@ -1349,18 +1349,15 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
>"Check shelf dip switches.\n");
>return;
>}
> -if (h->minor >= NPERSHELF) {
> -pr_err("aoe: e%ld.%d %s, %d\n",
> -aoemajor, h->minor,
> -"slot number larger than the maximum",
> -NPERSHELF-1);
> +if (aoemajor > AOE_MAXSHELF) {
> +pr_info("aoe: e%ld.%d: shelf number too large\n",
> +aoemajor, (int) h->minor);
>return;
>}
> 
> -sysminor = SYSMINOR(aoemajor, h->minor);
> -if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) {
> -printk(KERN_INFO "aoe: e%ld.%d: minor number too large\n",
> -aoemajor, (int) h->minor);
> +d = aoedev_by_aoeaddr(aoemajor, h->minor, 1);
> +if (d == NULL) {
> +pr_info("aoe: device allocation failure\n");
>return;
>}
> 
> @@ -1368,12 +1365,6 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
>if (n > aoe_maxout)/* keep it reasonable */
>n = aoe_maxout;
> 
> -d = 

Re: [PATCH 1/7] aoe: support more AoE addresses with dynamic block device minor numbers

2012-10-02 Thread Ed Cashin
I should have mentioned that these seven patches were made for linux-next/akpm, 
which contains the last 14-patch series for aoe.

On Oct 1, 2012, at 9:59 PM, Ed Cashin ecas...@coraid.com wrote:

 The ATA over Ethernet protocol uses a major (shelf) and
 minor (slot) address to identify a particular storage target.
 These changes remove an artificial limitation the aoe driver
 imposes on the use of AoE addresses.  For example, without these
 changes, the slot address has a maximum of 15, but users commonly
 use slot numbers much greater than that.
 
 The AoE shelf and slot address space is often used sparsely.
 Instead of using a static mapping between AoE addresses and the
 block device minor number, the block device minor numbers are now
 allocated on demand.
 
 Signed-off-by: Ed Cashin ecas...@coraid.com
 ---
 drivers/block/aoe/aoe.h|6 ++--
 drivers/block/aoe/aoeblk.c |2 +-
 drivers/block/aoe/aoechr.c |2 +-
 drivers/block/aoe/aoecmd.c |   25 -
 drivers/block/aoe/aoedev.c |   86 ++--
 5 files changed, 72 insertions(+), 49 deletions(-)
 
 diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
 index 27d0a21..7b694f7 100644
 --- a/drivers/block/aoe/aoe.h
 +++ b/drivers/block/aoe/aoe.h
 @@ -49,6 +49,8 @@ struct aoe_hdr {
__be32 tag;
 };
 
 +#define AOE_MAXSHELF (0x-1)/* one less than the broadcast shelf 
 address */
 +
 struct aoe_atahdr {
unsigned char aflags;
unsigned char errfeat;
 @@ -211,8 +213,7 @@ void aoe_ktstop(struct ktstate *k);
 
 int aoedev_init(void);
 void aoedev_exit(void);
 -struct aoedev *aoedev_by_aoeaddr(int maj, int min);
 -struct aoedev *aoedev_by_sysminor_m(ulong sysminor);
 +struct aoedev *aoedev_by_aoeaddr(ulong maj, int min, int do_alloc);
 void aoedev_downdev(struct aoedev *d);
 int aoedev_flush(const char __user *str, size_t size);
 void aoe_failbuf(struct aoedev *, struct buf *);
 @@ -223,4 +224,3 @@ void aoenet_exit(void);
 void aoenet_xmit(struct sk_buff_head *);
 int is_aoe_netif(struct net_device *ifp);
 int set_aoe_iflist(const char __user *str, size_t size);
 -
 diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
 index 83160ab..00dfc50 100644
 --- a/drivers/block/aoe/aoeblk.c
 +++ b/drivers/block/aoe/aoeblk.c
 @@ -249,7 +249,7 @@ aoeblk_gdalloc(void *vp)
q-queuedata = d;
d-gd = gd;
gd-major = AOE_MAJOR;
 -gd-first_minor = d-sysminor * AOE_PARTITIONS;
 +gd-first_minor = d-sysminor;
gd-fops = aoe_bdops;
gd-private_data = d;
set_capacity(gd, d-ssize);
 diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
 index deb30c1..ed57a89 100644
 --- a/drivers/block/aoe/aoechr.c
 +++ b/drivers/block/aoe/aoechr.c
 @@ -91,7 +91,7 @@ revalidate(const char __user *str, size_t size)
pr_err(aoe: invalid device specification %s\n, buf);
return -EINVAL;
}
 -d = aoedev_by_aoeaddr(major, minor);
 +d = aoedev_by_aoeaddr(major, minor, 0);
if (!d)
return -EINVAL;
spin_lock_irqsave(d-lock, flags);
 diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
 index 39dacdb..94e810c 100644
 --- a/drivers/block/aoe/aoecmd.c
 +++ b/drivers/block/aoe/aoecmd.c
 @@ -1149,7 +1149,7 @@ aoecmd_ata_rsp(struct sk_buff *skb)
 
h = (struct aoe_hdr *) skb-data;
aoemajor = be16_to_cpu(get_unaligned(h-major));
 -d = aoedev_by_aoeaddr(aoemajor, h-minor);
 +d = aoedev_by_aoeaddr(aoemajor, h-minor, 0);
if (d == NULL) {
snprintf(ebuf, sizeof ebuf, aoecmd_ata_rsp: ata response 
for unknown device %d.%d\n,
 @@ -1330,7 +1330,7 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
struct aoe_hdr *h;
struct aoe_cfghdr *ch;
struct aoetgt *t;
 -ulong flags, sysminor, aoemajor;
 +ulong flags, aoemajor;
struct sk_buff *sl;
struct sk_buff_head queue;
u16 n;
 @@ -1349,18 +1349,15 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
Check shelf dip switches.\n);
return;
}
 -if (h-minor = NPERSHELF) {
 -pr_err(aoe: e%ld.%d %s, %d\n,
 -aoemajor, h-minor,
 -slot number larger than the maximum,
 -NPERSHELF-1);
 +if (aoemajor  AOE_MAXSHELF) {
 +pr_info(aoe: e%ld.%d: shelf number too large\n,
 +aoemajor, (int) h-minor);
return;
}
 
 -sysminor = SYSMINOR(aoemajor, h-minor);
 -if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS  MINORMASK) {
 -printk(KERN_INFO aoe: e%ld.%d: minor number too large\n,
 -aoemajor, (int) h-minor);
 +d = aoedev_by_aoeaddr(aoemajor, h-minor, 1);
 +if (d == NULL) {
 +pr_info(aoe: device allocation failure\n);
return;
}
 
 @@ -1368,12 +1365,6 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
if (n  aoe_maxout)/* keep it reasonable */
n = aoe_maxout;
 
 -d = aoedev_by_sysminor_m(sysminor);
 -if (d == NULL) {
 -printk(KERN_INFO aoe: device sysminor_m failure\n);
 -return;
 -}

Re: [PATCH 1/7] aoe: support more AoE addresses with dynamic block device minor numbers

2012-10-02 Thread Andrew Morton
On Mon, 1 Oct 2012 18:59:12 -0700
Ed Cashin ecas...@coraid.com wrote:

 The ATA over Ethernet protocol uses a major (shelf) and
 minor (slot) address to identify a particular storage target.
 These changes remove an artificial limitation the aoe driver
 imposes on the use of AoE addresses.  For example, without these
 changes, the slot address has a maximum of 15, but users commonly
 use slot numbers much greater than that.
 
 The AoE shelf and slot address space is often used sparsely.
 Instead of using a static mapping between AoE addresses and the
 block device minor number, the block device minor numbers are now
 allocated on demand.
 
 ...

Very minor things...


 ...

 +static int
 +minor_get(ulong *minor)
  {
 - struct aoedev *d;
   ulong flags;
 + ulong n;
 + int error = 0;
 +
 + spin_lock_irqsave(used_minors_lock, flags);
 + n = find_first_zero_bit(used_minors, N_DEVS);
 + if (n  N_DEVS)
 + set_bit(n, used_minors);
 + else
 + error = -1;
 + spin_unlock_irqrestore(used_minors_lock, flags);
 +
 + *minor = n * AOE_PARTITIONS;
 + return error;
 +}

- can use the more efficient __set_bit() inside that spinlock.

- could avoid setting *minor if we're returning an error.

 - spin_lock_irqsave(devlist_lock, flags);
 +static void
 +minor_free(ulong minor)
 +{
 + ulong flags;
  
 - for (d=devlist; d; d=d-next)
 - if (d-aoemajor == maj  d-aoeminor == min) {
 - d-ref++;
 - break;
 - }
 + minor /= AOE_PARTITIONS;
 + BUG_ON(minor = N_DEVS);
  
 - spin_unlock_irqrestore(devlist_lock, flags);
 - return d;
 + spin_lock_irqsave(used_minors_lock, flags);
 + BUG_ON(!test_bit(minor, used_minors));
 + clear_bit(minor, used_minors);
 + spin_unlock_irqrestore(used_minors_lock, flags);
  }

Could use

BUG_ON(!__test_and_clear_bit(...));

This will work, but I think it's bad form to put an expression with
side-effects inside an assert macro.


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/7] aoe: support more AoE addresses with dynamic block device minor numbers

2012-10-02 Thread Ed Cashin
On Oct 2, 2012, at 5:12 PM, Andrew Morton wrote:
...
 +static int
 +minor_get(ulong *minor)
 {
 -struct aoedev *d;
  ulong flags;
 +ulong n;
 +int error = 0;
 +
 +spin_lock_irqsave(used_minors_lock, flags);
 +n = find_first_zero_bit(used_minors, N_DEVS);
 +if (n  N_DEVS)
 +set_bit(n, used_minors);
 +else
 +error = -1;
 +spin_unlock_irqrestore(used_minors_lock, flags);
 +
 +*minor = n * AOE_PARTITIONS;
 +return error;
 +}
 
 - can use the more efficient __set_bit() inside that spinlock.

Thanks for that observation.  Because this operation occurs on target 
discovery, which is expected to be relatively infrequent, my inclination is to 
leave it in its atomic form, though, and leave the __set_bit() for another time 
when optimization is needed.  Like you said, this is a minor point.  I wouldn't 
mind changing it, though, if you think it's worth me resubmitting the patch.  
Just let me know.

 - could avoid setting *minor if we're returning an error.

Yes.  The only caller of aoedev.c:minor_get() handles that correctly.  Again, 
just let me know if you think this is worth a resubmission of the patch.  
Otherwise I'll just make a note to myself to try to avoid setting output 
parameters on error in the future.

-- 
  Ed Cashin
  ecas...@coraid.com


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/