Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9bb8fb0 authored by David S. Miller's avatar David S. Miller
Browse files

aoe: Use SKB interfaces for list management instead of home-grown stuff.

parent 67fed459
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -159,11 +159,8 @@ struct aoedev {
	sector_t ssize;
	struct timer_list timer;
	spinlock_t lock;
	struct sk_buff *sendq_hd; /* packets needing to be sent, list head */
	struct sk_buff *sendq_tl;
	struct sk_buff *skbpool_hd;
	struct sk_buff *skbpool_tl;
	int nskbpool;
	struct sk_buff_head sendq;
	struct sk_buff_head skbpool;
	mempool_t *bufpool;	/* for deadlock-free Buf allocation */
	struct list_head bufq;	/* queue of bios to work on */
	struct buf *inprocess;	/* the one we're currently working on */
@@ -199,7 +196,7 @@ int aoedev_flush(const char __user *str, size_t size);

int aoenet_init(void);
void aoenet_exit(void);
void aoenet_xmit(struct sk_buff *);
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);

+4 −4
Original line number Diff line number Diff line
@@ -158,9 +158,9 @@ aoeblk_release(struct inode *inode, struct file *filp)
static int
aoeblk_make_request(struct request_queue *q, struct bio *bio)
{
	struct sk_buff_head queue;
	struct aoedev *d;
	struct buf *buf;
	struct sk_buff *sl;
	ulong flags;

	blk_queue_bounce(q, &bio);
@@ -213,11 +213,11 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio)
	list_add_tail(&buf->bufs, &d->bufq);

	aoecmd_work(d);
	sl = d->sendq_hd;
	d->sendq_hd = d->sendq_tl = NULL;
	__skb_queue_head_init(&queue);
	skb_queue_splice_init(&d->sendq, &queue);

	spin_unlock_irqrestore(&d->lock, flags);
	aoenet_xmit(sl);
	aoenet_xmit(&queue);

	return 0;
}
+7 −1
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/smp_lock.h>
#include <linux/skbuff.h>
#include "aoe.h"

enum {
@@ -103,7 +104,12 @@ loop:
		spin_lock_irqsave(&d->lock, flags);
		goto loop;
	}
	aoenet_xmit(skb);
	if (skb) {
		struct sk_buff_head queue;
		__skb_queue_head_init(&queue);
		__skb_queue_tail(&queue, skb);
		aoenet_xmit(&queue);
	}
	aoecmd_cfg(major, minor);
	return 0;
}
+32 −53
Original line number Diff line number Diff line
@@ -114,29 +114,22 @@ ifrotate(struct aoetgt *t)
static void
skb_pool_put(struct aoedev *d, struct sk_buff *skb)
{
	if (!d->skbpool_hd)
		d->skbpool_hd = skb;
	else
		d->skbpool_tl->next = skb;
	d->skbpool_tl = skb;
	__skb_queue_tail(&d->skbpool, skb);
}

static struct sk_buff *
skb_pool_get(struct aoedev *d)
{
	struct sk_buff *skb;
	struct sk_buff *skb = skb_peek(&d->skbpool);

	skb = d->skbpool_hd;
	if (skb && atomic_read(&skb_shinfo(skb)->dataref) == 1) {
		d->skbpool_hd = skb->next;
		skb->next = NULL;
		__skb_unlink(skb, &d->skbpool);
		return skb;
	}
	if (d->nskbpool < NSKBPOOLMAX
	&& (skb = new_skb(ETH_ZLEN))) {
		d->nskbpool++;
	if (skb_queue_len(&d->skbpool) < NSKBPOOLMAX &&
	    (skb = new_skb(ETH_ZLEN)))
		return skb;
	}

	return NULL;
}

@@ -293,29 +286,22 @@ aoecmd_ata_rw(struct aoedev *d)

	skb->dev = t->ifp->nd;
	skb = skb_clone(skb, GFP_ATOMIC);
	if (skb) {
		if (d->sendq_hd)
			d->sendq_tl->next = skb;
		else
			d->sendq_hd = skb;
		d->sendq_tl = skb;
	}
	if (skb)
		__skb_queue_tail(&d->sendq, skb);
	return 1;
}

/* some callers cannot sleep, and they can call this function,
 * transmitting the packets later, when interrupts are on
 */
static struct sk_buff *
aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
static void
aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *queue)
{
	struct aoe_hdr *h;
	struct aoe_cfghdr *ch;
	struct sk_buff *skb, *sl, *sl_tail;
	struct sk_buff *skb;
	struct net_device *ifp;

	sl = sl_tail = NULL;

	read_lock(&dev_base_lock);
	for_each_netdev(&init_net, ifp) {
		dev_hold(ifp);
@@ -329,8 +315,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
		}
		skb_put(skb, sizeof *h + sizeof *ch);
		skb->dev = ifp;
		if (sl_tail == NULL)
			sl_tail = skb;
		__skb_queue_tail(queue, skb);
		h = (struct aoe_hdr *) skb_mac_header(skb);
		memset(h, 0, sizeof *h + sizeof *ch);

@@ -342,16 +327,10 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
		h->minor = aoeminor;
		h->cmd = AOECMD_CFG;

		skb->next = sl;
		sl = skb;
cont:
		dev_put(ifp);
	}
	read_unlock(&dev_base_lock);

	if (tail != NULL)
		*tail = sl_tail;
	return sl;
}

static void
@@ -406,11 +385,7 @@ resend(struct aoedev *d, struct aoetgt *t, struct frame *f)
	skb = skb_clone(skb, GFP_ATOMIC);
	if (skb == NULL)
		return;
	if (d->sendq_hd)
		d->sendq_tl->next = skb;
	else
		d->sendq_hd = skb;
	d->sendq_tl = skb;
	__skb_queue_tail(&d->sendq, skb);
}

static int
@@ -508,16 +483,15 @@ ata_scnt(unsigned char *packet) {
static void
rexmit_timer(ulong vp)
{
	struct sk_buff_head queue;
	struct aoedev *d;
	struct aoetgt *t, **tt, **te;
	struct aoeif *ifp;
	struct frame *f, *e;
	struct sk_buff *sl;
	register long timeout;
	ulong flags, n;

	d = (struct aoedev *) vp;
	sl = NULL;

	/* timeout is always ~150% of the moving average */
	timeout = d->rttavg;
@@ -589,7 +563,7 @@ rexmit_timer(ulong vp)
		}
	}

	if (d->sendq_hd) {
	if (!skb_queue_empty(&d->sendq)) {
		n = d->rttavg <<= 1;
		if (n > MAXTIMER)
			d->rttavg = MAXTIMER;
@@ -600,15 +574,15 @@ rexmit_timer(ulong vp)
		aoecmd_work(d);
	}

	sl = d->sendq_hd;
	d->sendq_hd = d->sendq_tl = NULL;
	__skb_queue_head_init(&queue);
	skb_queue_splice_init(&d->sendq, &queue);

	d->timer.expires = jiffies + TIMERTICK;
	add_timer(&d->timer);

	spin_unlock_irqrestore(&d->lock, flags);

	aoenet_xmit(sl);
	aoenet_xmit(&queue);
}

/* enters with d->lock held */
@@ -767,12 +741,12 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector
void
aoecmd_ata_rsp(struct sk_buff *skb)
{
	struct sk_buff_head queue;
	struct aoedev *d;
	struct aoe_hdr *hin, *hout;
	struct aoe_atahdr *ahin, *ahout;
	struct frame *f;
	struct buf *buf;
	struct sk_buff *sl;
	struct aoetgt *t;
	struct aoeif *ifp;
	register long n;
@@ -893,21 +867,21 @@ aoecmd_ata_rsp(struct sk_buff *skb)

	aoecmd_work(d);
xmit:
	sl = d->sendq_hd;
	d->sendq_hd = d->sendq_tl = NULL;
	__skb_queue_head_init(&queue);
	skb_queue_splice_init(&d->sendq, &queue);

	spin_unlock_irqrestore(&d->lock, flags);
	aoenet_xmit(sl);
	aoenet_xmit(&queue);
}

void
aoecmd_cfg(ushort aoemajor, unsigned char aoeminor)
{
	struct sk_buff *sl;

	sl = aoecmd_cfg_pkts(aoemajor, aoeminor, NULL);
	struct sk_buff_head queue;

	aoenet_xmit(sl);
	__skb_queue_head_init(&queue);
	aoecmd_cfg_pkts(aoemajor, aoeminor, &queue);
	aoenet_xmit(&queue);
}
 
struct sk_buff *
@@ -1076,7 +1050,12 @@ aoecmd_cfg_rsp(struct sk_buff *skb)

	spin_unlock_irqrestore(&d->lock, flags);

	aoenet_xmit(sl);
	if (sl) {
		struct sk_buff_head queue;
		__skb_queue_head_init(&queue);
		__skb_queue_tail(&queue, sl);
		aoenet_xmit(&queue);
	}
}

void
+6 −6
Original line number Diff line number Diff line
@@ -188,14 +188,12 @@ skbfree(struct sk_buff *skb)
static void
skbpoolfree(struct aoedev *d)
{
	struct sk_buff *skb;
	struct sk_buff *skb, *tmp;

	while ((skb = d->skbpool_hd)) {
		d->skbpool_hd = skb->next;
		skb->next = NULL;
	skb_queue_walk_safe(&d->skbpool, skb, tmp)
		skbfree(skb);
	}
	d->skbpool_tl = NULL;

	__skb_queue_head_init(&d->skbpool);
}

/* find it or malloc it */
@@ -217,6 +215,8 @@ aoedev_by_sysminor_m(ulong sysminor)
		goto out;
	INIT_WORK(&d->work, aoecmd_sleepwork);
	spin_lock_init(&d->lock);
	skb_queue_head_init(&d->sendq);
	skb_queue_head_init(&d->skbpool);
	init_timer(&d->timer);
	d->timer.data = (ulong) d;
	d->timer.function = dummy_timer;
Loading