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

Commit 4c31c303 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block

* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
  Add UNPLUG traces to all appropriate places
  block: fix requeue handling in blk_queue_invalidate_tags()
  mmc: Fix sg helper copy-and-paste error
  pktcdvd: fix BUG caused by sysfs module reference semantics change
  ioprio: allow sys_ioprio_set() value of 0 to reset ioprio setting
  cfq_idle_class_timer: add paranoid checks for jiffies overflow
  cfq: fix IOPRIO_CLASS_IDLE delays
  cfq: fix IOPRIO_CLASS_IDLE accounting
parents c4888f9f 2ad8b1ef
Loading
Loading
Loading
Loading
+21 −13
Original line number Diff line number Diff line
@@ -789,6 +789,20 @@ static inline void cfq_slice_expired(struct cfq_data *cfqd, int timed_out)
		__cfq_slice_expired(cfqd, cfqq, timed_out);
}

static int start_idle_class_timer(struct cfq_data *cfqd)
{
	unsigned long end = cfqd->last_end_request + CFQ_IDLE_GRACE;
	unsigned long now = jiffies;

	if (time_before(now, end) &&
	    time_after_eq(now, cfqd->last_end_request)) {
		mod_timer(&cfqd->idle_class_timer, end);
		return 1;
	}

	return 0;
}

/*
 * Get next queue for service. Unless we have a queue preemption,
 * we'll simply select the first cfqq in the service tree.
@@ -805,20 +819,15 @@ static struct cfq_queue *cfq_get_next_queue(struct cfq_data *cfqd)
	cfqq = rb_entry(n, struct cfq_queue, rb_node);

	if (cfq_class_idle(cfqq)) {
		unsigned long end;

		/*
		 * if we have idle queues and no rt or be queues had
		 * pending requests, either allow immediate service if
		 * the grace period has passed or arm the idle grace
		 * timer
		 */
		end = cfqd->last_end_request + CFQ_IDLE_GRACE;
		if (time_before(jiffies, end)) {
			mod_timer(&cfqd->idle_class_timer, end);
		if (start_idle_class_timer(cfqd))
			cfqq = NULL;
	}
	}

	return cfqq;
}
@@ -2036,17 +2045,14 @@ static void cfq_idle_slice_timer(unsigned long data)
static void cfq_idle_class_timer(unsigned long data)
{
	struct cfq_data *cfqd = (struct cfq_data *) data;
	unsigned long flags, end;
	unsigned long flags;

	spin_lock_irqsave(cfqd->queue->queue_lock, flags);

	/*
	 * race with a non-idle queue, reset timer
	 */
	end = cfqd->last_end_request + CFQ_IDLE_GRACE;
	if (!time_after_eq(jiffies, end))
		mod_timer(&cfqd->idle_class_timer, end);
	else
	if (!start_idle_class_timer(cfqd))
		cfq_schedule_dispatch(cfqd);

	spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
@@ -2068,10 +2074,11 @@ static void cfq_put_async_queues(struct cfq_data *cfqd)
			cfq_put_queue(cfqd->async_cfqq[0][i]);
		if (cfqd->async_cfqq[1][i])
			cfq_put_queue(cfqd->async_cfqq[1][i]);
	}

	if (cfqd->async_idle_cfqq)
		cfq_put_queue(cfqd->async_idle_cfqq);
}
}

static void cfq_exit_queue(elevator_t *e)
{
@@ -2125,6 +2132,7 @@ static void *cfq_init_queue(struct request_queue *q)

	INIT_WORK(&cfqd->unplug_work, cfq_kick_queue);

	cfqd->last_end_request = jiffies;
	cfqd->cfq_quantum = cfq_quantum;
	cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0];
	cfqd->cfq_fifo_expire[1] = cfq_fifo_expire[1];
+17 −24
Original line number Diff line number Diff line
@@ -1143,22 +1143,9 @@ EXPORT_SYMBOL(blk_queue_start_tag);
void blk_queue_invalidate_tags(struct request_queue *q)
{
	struct list_head *tmp, *n;
	struct request *rq;

	list_for_each_safe(tmp, n, &q->tag_busy_list) {
		rq = list_entry_rq(tmp);

		if (rq->tag == -1) {
			printk(KERN_ERR
			       "%s: bad tag found on list\n", __FUNCTION__);
			list_del_init(&rq->queuelist);
			rq->cmd_flags &= ~REQ_QUEUED;
		} else
			blk_queue_end_tag(q, rq);

		rq->cmd_flags &= ~REQ_STARTED;
		__elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 0);
	}
	list_for_each_safe(tmp, n, &q->tag_busy_list)
		blk_requeue_request(q, list_entry_rq(tmp));
}

EXPORT_SYMBOL(blk_queue_invalidate_tags);
@@ -1634,15 +1621,7 @@ static void blk_backing_dev_unplug(struct backing_dev_info *bdi,
{
	struct request_queue *q = bdi->unplug_io_data;

	/*
	 * devices don't necessarily have an ->unplug_fn defined
	 */
	if (q->unplug_fn) {
		blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_IO, NULL,
					q->rq.count[READ] + q->rq.count[WRITE]);

		q->unplug_fn(q);
	}
	blk_unplug(q);
}

static void blk_unplug_work(struct work_struct *work)
@@ -1666,6 +1645,20 @@ static void blk_unplug_timeout(unsigned long data)
	kblockd_schedule_work(&q->unplug_work);
}

void blk_unplug(struct request_queue *q)
{
	/*
	 * devices don't necessarily have an ->unplug_fn defined
	 */
	if (q->unplug_fn) {
		blk_add_trace_pdu_int(q, BLK_TA_UNPLUG_IO, NULL,
					q->rq.count[READ] + q->rq.count[WRITE]);

		q->unplug_fn(q);
	}
}
EXPORT_SYMBOL(blk_unplug);

/**
 * blk_start_queue - restart a previously stopped queue
 * @q:    The &struct request_queue in question
+9 −0
Original line number Diff line number Diff line
@@ -358,10 +358,19 @@ static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf,
					size_t count)
{
	unsigned int major, minor;

	if (sscanf(buf, "%u:%u", &major, &minor) == 2) {
		/* pkt_setup_dev() expects caller to hold reference to self */
		if (!try_module_get(THIS_MODULE))
			return -ENODEV;

		pkt_setup_dev(MKDEV(major, minor), NULL);

		module_put(THIS_MODULE);

		return count;
	}

	return -EINVAL;
}

+1 −2
Original line number Diff line number Diff line
@@ -1207,8 +1207,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect
			prepare_to_wait(&bitmap->overflow_wait, &__wait,
					TASK_UNINTERRUPTIBLE);
			spin_unlock_irq(&bitmap->lock);
			bitmap->mddev->queue
				->unplug_fn(bitmap->mddev->queue);
			blk_unplug(bitmap->mddev->queue);
			schedule();
			finish_wait(&bitmap->overflow_wait, &__wait);
			continue;
+1 −2
Original line number Diff line number Diff line
@@ -1000,8 +1000,7 @@ void dm_table_unplug_all(struct dm_table *t)
		struct dm_dev *dd = list_entry(d, struct dm_dev, list);
		struct request_queue *q = bdev_get_queue(dd->bdev);

		if (q->unplug_fn)
			q->unplug_fn(q);
		blk_unplug(q);
	}
}

Loading