static void mt76x0_tx_tasklet(unsigned long data) { struct mt76x0_dev *dev = (struct mt76x0_dev *) data; struct sk_buff_head skbs; unsigned long flags; __skb_queue_head_init(&skbs); spin_lock_irqsave(&dev->tx_lock, flags); set_bit(MT76_MORE_STATS, &dev->mt76.state); if (!test_and_set_bit(MT76_READING_STATS, &dev->mt76.state)) queue_delayed_work(dev->stat_wq, &dev->stat_work, msecs_to_jiffies(10)); skb_queue_splice_init(&dev->tx_skb_done, &skbs); spin_unlock_irqrestore(&dev->tx_lock, flags); while (!skb_queue_empty(&skbs)) { struct sk_buff *skb = __skb_dequeue(&skbs); mt76x0_tx_status(dev, skb); } }
void xfrm_dev_backlog(struct softnet_data *sd) { struct sk_buff_head *xfrm_backlog = &sd->xfrm_backlog; struct sk_buff_head list; struct sk_buff *skb; if (skb_queue_empty(xfrm_backlog)) return; __skb_queue_head_init(&list); spin_lock(&xfrm_backlog->lock); skb_queue_splice_init(xfrm_backlog, &list); spin_unlock(&xfrm_backlog->lock); while (!skb_queue_empty(&list)) { skb = __skb_dequeue(&list); xfrm_dev_resume(skb); } }
static int aoeblk_make_request(struct request_queue *q, struct bio *bio) { struct sk_buff_head queue; struct aoedev *d; struct buf *buf; ulong flags; blk_queue_bounce(q, &bio); if (bio == NULL) { printk(KERN_ERR "aoe: bio is NULL\n"); BUG(); return 0; } d = bio->bi_bdev->bd_disk->private_data; if (d == NULL) { printk(KERN_ERR "aoe: bd_disk->private_data is NULL\n"); BUG(); bio_endio(bio, -ENXIO); return 0; } else if (bio->bi_io_vec == NULL) { printk(KERN_ERR "aoe: bi_io_vec is NULL\n"); BUG(); bio_endio(bio, -ENXIO); return 0; } buf = mempool_alloc(d->bufpool, GFP_NOIO); if (buf == NULL) { printk(KERN_INFO "aoe: buf allocation failure\n"); bio_endio(bio, -ENOMEM); return 0; } memset(buf, 0, sizeof(*buf)); INIT_LIST_HEAD(&buf->bufs); buf->stime = jiffies; buf->bio = bio; buf->resid = bio->bi_size; buf->sector = bio->bi_sector; buf->bv = &bio->bi_io_vec[bio->bi_idx]; buf->bv_resid = buf->bv->bv_len; WARN_ON(buf->bv_resid == 0); buf->bv_off = buf->bv->bv_offset; spin_lock_irqsave(&d->lock, flags); if ((d->flags & DEVFL_UP) == 0) { pr_info_ratelimited("aoe: device %ld.%d is not up\n", d->aoemajor, d->aoeminor); spin_unlock_irqrestore(&d->lock, flags); mempool_free(buf, d->bufpool); bio_endio(bio, -ENXIO); return 0; } list_add_tail(&buf->bufs, &d->bufq); aoecmd_work(d); __skb_queue_head_init(&queue); skb_queue_splice_init(&d->sendq, &queue); spin_unlock_irqrestore(&d->lock, flags); aoenet_xmit(&queue); return 0; }
inline struct sk_buff *skb_recycler_alloc(struct net_device *dev, unsigned int length) { unsigned long flags; struct sk_buff_head *h; struct sk_buff *skb = NULL; if (unlikely(length > SKB_RECYCLE_SIZE)) { return NULL; } h = &get_cpu_var(recycle_list); local_irq_save(flags); skb = __skb_dequeue(h); #ifdef CONFIG_SKB_RECYCLER_MULTI_CPU if (unlikely(!skb)) { uint8_t head; spin_lock(&glob_recycler.lock); /* If global recycle list is not empty, use global buffers */ head = glob_recycler.head; if (likely(head != glob_recycler.tail)) { /* Move SKBs from global list to CPU pool */ skb_queue_splice_init(&glob_recycler.pool[head], h); head = (head + 1) & SKB_RECYCLE_MAX_SHARED_POOLS_MASK; glob_recycler.head = head; spin_unlock(&glob_recycler.lock); /* We have refilled the CPU pool - dequeue */ skb = __skb_dequeue(h); } else { spin_unlock(&glob_recycler.lock); } } #endif local_irq_restore(flags); put_cpu_var(recycle_list); if (likely(skb)) { struct skb_shared_info *shinfo; /* * We're about to write a large amount to the skb to * zero most of the structure so prefetch the start * of the shinfo region now so it's in the D-cache * before we start to write that. */ shinfo = skb_shinfo(skb); prefetchw(shinfo); zero_struct(skb, offsetof(struct sk_buff, tail)); skb->data = skb->head; skb_reset_tail_pointer(skb); #ifdef NET_SKBUFF_DATA_USES_OFFSET skb->mac_header = ~0U; #endif zero_struct(shinfo, offsetof(struct skb_shared_info, dataref)); atomic_set(&shinfo->dataref, 1); skb_reserve(skb, NET_SKB_PAD); if (dev) { skb->dev = dev; } } return skb; }