code:
From 124298bd03acebd9c9da29a794718aca31bec1f7 Mon Sep 17 00:00:00 2001
From: Daniel Roschka <danielroschka@phoenitydawn.de>
Date: Wed, 22 Feb 2017 15:17:29 -0700
Subject: [PATCH] nvme: detect NVMe controller in recent MacBooks

Adds support for detection of the NVMe controller found in the
following recent MacBooks:
- Retina MacBook 2016 (MacBook9,1)
- 13" MacBook Pro 2016 without Touch Bar (MacBook13,1)
- 13" MacBook Pro 2016 with Touch Bar (MacBook13,2)

Signed-off-by: Daniel Roschka <danielroschka@phoenitydawn.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Jens Axboe <axboe@fb.com>
---
 drivers/nvme/host/pci.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index d38dae9..319f5c5 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -2120,6 +2120,7 @@ static const struct pci_device_id nvme_id_table[] = {
 		.driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
 	{ PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) },
 	{ 0, }
 };
 MODULE_DEVICE_TABLE(pci, nvme_id_table);
--
2.10.2

repo_name: ayhanyalcinsoy/main


code:
 block/bfq-iosched.c |  4 +++-
 block/bfq-sched.c   | 15 ++++++++++++---
 block/bfq.h         |  2 +-
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 96b79a0dae9f..158628392d92 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -4572,6 +4572,8 @@ static int bfq_set_request(struct request_queue *q, struct request *rq,
 	if (!bic)
 		goto queue_fail;

+	bfq_check_ioprio_change(bic, bio);
+
 	bfq_bic_update_cgroup(bic, bio);

 new_queue:
@@ -5268,7 +5270,7 @@ static struct blkcg_policy blkcg_policy_bfq = {
 static int __init bfq_init(void)
 {
 	int ret;
-	char msg[60] = "BFQ I/O-scheduler: v8r10";
+	char msg[60] = "BFQ I/O-scheduler: v8r11";

 #ifdef CONFIG_BFQ_GROUP_IOSCHED
 	ret = blkcg_policy_register(&blkcg_policy_bfq);
diff --git a/block/bfq-sched.c b/block/bfq-sched.c
index 70aac56b02ef..8311bdbeceea 100644
--- a/block/bfq-sched.c
+++ b/block/bfq-sched.c
@@ -1280,14 +1280,23 @@ static bool __bfq_deactivate_entity(struct bfq_entity *entity,
 				    bool ins_into_idle_tree)
 {
 	struct bfq_sched_data *sd = entity->sched_data;
-	struct bfq_service_tree *st = bfq_entity_service_tree(entity);
-	bool is_in_service = entity == sd->in_service_entity;
+	struct bfq_service_tree *st;
+	bool is_in_service;

 	if (!entity->on_st) { /* entity never activated, or already inactive */
-		BUG_ON(entity == entity->sched_data->in_service_entity);
+		BUG_ON(sd && entity == sd->in_service_entity);
 		return false;
 	}

+	/*
+	 * If we get here, then entity is active, which implies that
+	 * bfq_group_set_parent has already been invoked for the group
+	 * represented by entity. Therefore, the field
+	 * entity->sched_data has been set, and we can safely use it.
+	 */
+	st = bfq_entity_service_tree(entity);
+	is_in_service = entity == sd->in_service_entity;
+
 	BUG_ON(is_in_service && entity->tree && entity->tree != &st->active);

 	if (is_in_service)
diff --git a/block/bfq.h b/block/bfq.h
index e3855af1211b..a521ac40cac0 100644
--- a/block/bfq.h
+++ b/block/bfq.h
@@ -1,5 +1,5 @@
 /*
- * BFQ v8r10 for 4.9.0: data structures and common functions prototypes.
+ * BFQ v8r11 for 4.9.0: data structures and common functions prototypes.
  *
  * Based on ideas and code from CFQ:
  * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>


code:
 block/bfq-cgroup.c  |  12 +--
 block/bfq-iosched.c | 211 +++++++++++++++++++++++++++++++---------------------
 block/bfq-sched.c   |  73 ++++++++++++------
 block/bfq.h         |   4 +-
 4 files changed, 180 insertions(+), 120 deletions(-)

diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
index bbaecd0..a66a723 100644
--- a/block/bfq-cgroup.c
+++ b/block/bfq-cgroup.c
@@ -771,7 +771,6 @@ static void bfq_pd_offline(struct blkg_policy_data *pd)

 	__bfq_deactivate_entity(entity, false);
 	bfq_put_async_queues(bfqd, bfqg);
-	BUG_ON(entity->tree);

 	/*
 	 * @blkg is going offline and will be ignored by
@@ -1140,6 +1139,9 @@ static inline void bfqg_stats_update_idle_time(struct bfq_group *bfqg) { }
 static inline void bfqg_stats_set_start_idle_time(struct bfq_group *bfqg) { }
 static inline void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg) { }

+static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+			  struct bfq_group *bfqg) {}
+
 static void bfq_init_entity(struct bfq_entity *entity,
 			    struct bfq_group *bfqg)
 {
@@ -1154,13 +1156,7 @@ static void bfq_init_entity(struct bfq_entity *entity,
 	entity->sched_data = &bfqg->sched_data;
 }

-static struct bfq_group *
-bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio)
-{
-	struct bfq_data *bfqd = bic_to_bfqd(bic);
-
-	return bfqd->root_group;
-}
+static void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio) {}

 static void bfq_end_wr_async(struct bfq_data *bfqd)
 {
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 78baa07..96b79a0 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -9,7 +9,7 @@
  *
  * Copyright (C) 2015 Paolo Valente <paolo.valente@unimore.it>
  *
- * Copyright (C) 2016 Paolo Valente <paolo.valente@linaro.org>
+ * Copyright (C) 2017 Paolo Valente <paolo.valente@linaro.org>
  *
  * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ
  * file.
@@ -107,7 +107,7 @@ static const int bfq_async_charge_factor = 10;
 /* Default timeout values, in jiffies, approximating CFQ defaults. */
 static const int bfq_timeout = (HZ / 8);

-struct kmem_cache *bfq_pool;
+static struct kmem_cache *bfq_pool;

 /* Below this threshold (in ns), we consider thinktime immediate. */
 #define BFQ_MIN_TT		(2 * NSEC_PER_MSEC)
@@ -483,6 +483,22 @@ static void bfq_weights_tree_add(struct bfq_data *bfqd,

 	entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter),
 					 GFP_ATOMIC);
+
+	/*
+	 * In the unlucky event of an allocation failure, we just
+	 * exit. This will cause the weight of entity to not be
+	 * considered in bfq_differentiated_weights, which, in its
+	 * turn, causes the scenario to be deemed wrongly symmetric in
+	 * case entity's weight would have been the only weight making
+	 * the scenario asymmetric. On the bright side, no unbalance
+	 * will however occur when entity becomes inactive again (the
+	 * invocation of this function is triggered by an activation
+	 * of entity). In fact, bfq_weights_tree_remove does nothing
+	 * if !entity->weight_counter.
+	 */
+	if (unlikely(!entity->weight_counter))
+		return;
+
 	entity->weight_counter->weight = entity->weight;
 	rb_link_node(&entity->weight_counter->weights_node, parent, new);
 	rb_insert_color(&entity->weight_counter->weights_node, root);
@@ -519,13 +535,45 @@ static void bfq_weights_tree_remove(struct bfq_data *bfqd,
 	entity->weight_counter = NULL;
 }

+/*
+ * Return expired entry, or NULL to just start from scratch in rbtree.
+ */
+static struct request *bfq_check_fifo(struct bfq_queue *bfqq,
+				      struct request *last)
+{
+	struct request *rq;
+
+	if (bfq_bfqq_fifo_expire(bfqq))
+		return NULL;
+
+	bfq_mark_bfqq_fifo_expire(bfqq);
+
+	rq = rq_entry_fifo(bfqq->fifo.next);
+
+	if (rq == last || ktime_get_ns() < rq->fifo_time)
+		return NULL;
+
+	bfq_log_bfqq(bfqq->bfqd, bfqq, "check_fifo: returned %p", rq);
+	BUG_ON(RB_EMPTY_NODE(&rq->rb_node));
+	return rq;
+}
+
 static struct request *bfq_find_next_rq(struct bfq_data *bfqd,
 					struct bfq_queue *bfqq,
 					struct request *last)
 {
 	struct rb_node *rbnext = rb_next(&last->rb_node);
 	struct rb_node *rbprev = rb_prev(&last->rb_node);
-	struct request *next = NULL, *prev = NULL;
+	struct request *next, *prev = NULL;
+
+	BUG_ON(list_empty(&bfqq->fifo));
+
+	/* Follow expired path, else get first next available. */
+	next = bfq_check_fifo(bfqq, last);
+	if (next) {
+		BUG_ON(next == last);
+		return next;
+	}

 	BUG_ON(RB_EMPTY_NODE(&last->rb_node));

@@ -1359,7 +1407,6 @@ static void bfq_bfqq_handle_idle_busy_switch(struct bfq_data *bfqd,

 		bfq_bfqq_expire(bfqd, bfqd->in_service_queue,
 				false, BFQ_BFQQ_PREEMPTED);
-		BUG_ON(in_serv->entity.budget < 0);
 	}
 }

@@ -1523,12 +1570,15 @@ static void bfq_remove_request(struct request *rq)
 	elv_rb_del(&bfqq->sort_list, rq);

 	if (RB_EMPTY_ROOT(&bfqq->sort_list)) {
+		bfqq->next_rq = NULL;
+
 		BUG_ON(bfqq->entity.budget < 0);

 		if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue) {
+			BUG_ON(bfqq->ref < 2); /* referred by rq and on tree */
 			bfq_del_bfqq_busy(bfqd, bfqq, false);
-
-			/* bfqq emptied. In normal operation, when
+			/*
+			 * bfqq emptied. In normal operation, when
 			 * bfqq is empty, bfqq->entity.service and
 			 * bfqq->entity.budget must contain,
 			 * respectively, the service received and the
@@ -1537,7 +1587,8 @@ static void bfq_remove_request(struct request *rq)
 			 * this last removal occurred while bfqq is
 			 * not in service. To avoid inconsistencies,
 			 * reset both bfqq->entity.service and
-			 * bfqq->entity.budget.
+			 * bfqq->entity.budget, if bfqq has still a
+			 * process that may issue I/O requests to it.
 			 */
 			bfqq->entity.budget = bfqq->entity.service = 0;
 		}
@@ -1868,7 +1919,7 @@ static bool bfq_may_be_close_cooperator(struct bfq_queue *bfqq,
  * positives. In case bfqq is weight-raised, such false positives
  * would evidently degrade latency guarantees for bfqq.
  */
-bool wr_from_too_long(struct bfq_queue *bfqq)
+static bool wr_from_too_long(struct bfq_queue *bfqq)
 {
 	return bfqq->wr_coeff > 1 &&
 		time_is_before_jiffies(bfqq->last_wr_start_finish +
@@ -2029,7 +2080,8 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic,
 		new_bfqq->wr_coeff = bfqq->wr_coeff;
 		new_bfqq->wr_cur_max_time = bfqq->wr_cur_max_time;
 		new_bfqq->last_wr_start_finish = bfqq->last_wr_start_finish;
-		new_bfqq->wr_start_at_switch_to_srt = bfqq->wr_start_at_switch_to_srt;
+		new_bfqq->wr_start_at_switch_to_srt =
+			bfqq->wr_start_at_switch_to_srt;
 		if (bfq_bfqq_busy(new_bfqq))
 			bfqd->wr_busy_queues++;
 		new_bfqq->entity.prio_changed = 1;
@@ -2072,6 +2124,7 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic,
 	 */
 	new_bfqq->bic = NULL;
 	bfqq->bic = NULL;
+	/* release process reference to bfqq */
 	bfq_put_queue(bfqq);
 }

@@ -2298,7 +2351,7 @@ static unsigned long bfq_calc_max_budget(struct bfq_data *bfqd)
  * function of the estimated peak rate. See comments on
  * bfq_calc_max_budget(), and on T_slow and T_fast arrays.
  */
-void update_thr_responsiveness_params(struct bfq_data *bfqd)
+static void update_thr_responsiveness_params(struct bfq_data *bfqd)
 {
 	int dev_type = blk_queue_nonrot(bfqd->queue);

@@ -2333,7 +2386,7 @@ void update_thr_responsiveness_params(struct bfq_data *bfqd)
 		BFQ_RATE_SHIFT);
 }

-void bfq_reset_rate_computation(struct bfq_data *bfqd, struct request *rq)
+static void bfq_reset_rate_computation(struct bfq_data *bfqd, struct request *rq)
 {
 	if (rq != NULL) { /* new rq dispatch now, reset accordingly */
 		bfqd->last_dispatch = bfqd->first_dispatch = ktime_get_ns() ;
@@ -2350,7 +2403,7 @@ void bfq_reset_rate_computation(struct bfq_data *bfqd, struct request *rq)
 		bfqd->tot_sectors_dispatched);
 }

-void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
+static void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
 {
 	u32 rate, weight, divisor;

@@ -2400,7 +2453,7 @@ void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
 	 *   total, and rate is below the current estimated peak rate
 	 * - rate is unreasonably high (> 20M sectors/sec)
 	 */
-	if ((bfqd->peak_rate_samples > (3 * bfqd->sequential_samples)>>2 &&
+	if ((bfqd->sequential_samples < (3 * bfqd->peak_rate_samples)>>2 &&
 	     rate <= bfqd->peak_rate) ||
 		rate > 20<<BFQ_RATE_SHIFT) {
 		bfq_log(bfqd,
@@ -2515,7 +2568,7 @@ void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
  * of the observed dispatch rate. The function assumes to be invoked
  * on every request dispatch.
  */
-void bfq_update_peak_rate(struct bfq_data *bfqd, struct request *rq)
+static void bfq_update_peak_rate(struct bfq_data *bfqd, struct request *rq)
 {
 	u64 now_ns = ktime_get_ns();

@@ -2616,29 +2669,6 @@ static void bfq_dispatch_insert(struct request_queue *q, struct request *rq)
 	elv_dispatch_sort(q, rq);
 }

-/*
- * Return expired entry, or NULL to just start from scratch in rbtree.
- */
-static struct request *bfq_check_fifo(struct bfq_queue *bfqq)
-{
-	struct request *rq = NULL;
-
-	if (bfq_bfqq_fifo_expire(bfqq))
-		return NULL;
-
-	bfq_mark_bfqq_fifo_expire(bfqq);
-
-	if (list_empty(&bfqq->fifo))
-		return NULL;
-
-	rq = rq_entry_fifo(bfqq->fifo.next);
-
-	if (ktime_get_ns() < rq->fifo_time)
-		return NULL;
-
-	return rq;
-}
-
 static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
 {
 	BUG_ON(bfqq != bfqd->in_service_queue);
@@ -2904,8 +2934,8 @@ static bool bfq_bfqq_is_slow(struct bfq_data *bfqd, struct bfq_queue *bfqq,
 	delta_ktime = ktime_sub(delta_ktime, bfqd->last_budget_start);
 	delta_usecs = ktime_to_us(delta_ktime);

-	/* don't trust short/unrealistic values. */
-	if (delta_usecs < 1000 || delta_usecs >= LONG_MAX) {
+	/* don't use too short time intervals */
+	if (delta_usecs < 1000) {
 		if (blk_queue_nonrot(bfqd->queue))
 			 /*
 			  * give same worst-case guarantees as idling
@@ -2915,7 +2945,7 @@ static bool bfq_bfqq_is_slow(struct bfq_data *bfqd, struct bfq_queue *bfqq,
 		else /* charge at least one seek */
 			*delta_ms = bfq_slice_idle / NSEC_PER_MSEC;

-		bfq_log(bfqd, "bfq_bfqq_is_slow: unrealistic %u", delta_usecs);
+		bfq_log(bfqd, "bfq_bfqq_is_slow: too short %u", delta_usecs);

 		return slow;
 	}
@@ -3067,6 +3097,7 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd,
 	bool slow;
 	unsigned long delta = 0;
 	struct bfq_entity *entity = &bfqq->entity;
+	int ref;

 	BUG_ON(bfqq != bfqd->in_service_queue);

@@ -3174,12 +3205,15 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd,
 	__bfq_bfqq_recalc_budget(bfqd, bfqq, reason);
 	BUG_ON(bfqq->next_rq == NULL &&
 	       bfqq->entity.budget < bfqq->entity.service);
+	ref = bfqq->ref;
 	__bfq_bfqq_expire(bfqd, bfqq);

-	BUG_ON(!bfq_bfqq_busy(bfqq) && reason == BFQ_BFQQ_BUDGET_EXHAUSTED &&
+	BUG_ON(ref > 1 &&
+	       !bfq_bfqq_busy(bfqq) && reason == BFQ_BFQQ_BUDGET_EXHAUSTED &&
 		!bfq_class_idle(bfqq));

-	if (!bfq_bfqq_busy(bfqq) &&
+	/* mark bfqq as waiting a request only if a bic still points to it */
+	if (ref > 1 && !bfq_bfqq_busy(bfqq) &&
 	    reason != BFQ_BFQQ_BUDGET_TIMEOUT &&
 	    reason != BFQ_BFQQ_BUDGET_EXHAUSTED)
 		bfq_mark_bfqq_non_blocking_wait_rq(bfqq);
@@ -3504,14 +3538,29 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
 	    !bfq_bfqq_must_idle(bfqq))
 		goto expire;

+check_queue:
+	/*
+	 * This loop is rarely executed more than once. Even when it
+	 * happens, it is much more convenient to re-execute this loop
+	 * than to return NULL and trigger a new dispatch to get a
+	 * request served.
+	 */
 	next_rq = bfqq->next_rq;
 	/*
 	 * If bfqq has requests queued and it has enough budget left to
 	 * serve them, keep the queue, otherwise expire it.
 	 */
 	if (next_rq) {
+		BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list));
+
 		if (bfq_serv_to_charge(next_rq, bfqq) >
 			bfq_bfqq_budget_left(bfqq)) {
+			/*
+			 * Expire the queue for budget exhaustion,
+			 * which makes sure that the next budget is
+			 * enough to serve the next request, even if
+			 * it comes from the fifo expired path.
+			 */
 			reason = BFQ_BFQQ_BUDGET_EXHAUSTED;
 			goto expire;
 		} else {
@@ -3559,9 +3608,16 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
 	bfq_bfqq_expire(bfqd, bfqq, false, reason);
 new_queue:
 	bfqq = bfq_set_in_service_queue(bfqd);
-	bfq_log(bfqd, "select_queue: new queue %d returned",
-		bfqq ? bfqq->pid : 0);
+	if (bfqq) {
+		bfq_log_bfqq(bfqd, bfqq, "select_queue: checking new queue");
+		goto check_queue;
+	}
 keep_queue:
+	if (bfqq)
+		bfq_log_bfqq(bfqd, bfqq, "select_queue: returned this queue");
+	else
+		bfq_log(bfqd, "select_queue: no queue returned");
+
 	return bfqq;
 }

@@ -3627,45 +3683,17 @@ static int bfq_dispatch_request(struct bfq_data *bfqd,
 				struct bfq_queue *bfqq)
 {
 	int dispatched = 0;
-	struct request *rq;
+	struct request *rq = bfqq->next_rq;
 	unsigned long service_to_charge;

 	BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list));
-
-	/* Follow expired path, else get first next available. */
-	rq = bfq_check_fifo(bfqq);
-	if (!rq)
-		rq = bfqq->next_rq;
+	BUG_ON(!rq);
 	service_to_charge = bfq_serv_to_charge(rq, bfqq);

-	if (service_to_charge > bfq_bfqq_budget_left(bfqq)) {
-		/*
-		 * This may happen if the next rq is chosen in fifo order
-		 * instead of sector order. The budget is properly
-		 * dimensioned to be always sufficient to serve the next
-		 * request only if it is chosen in sector order. The reason
-		 * is that it would be quite inefficient and little useful
-		 * to always make sure that the budget is large enough to
-		 * serve even the possible next rq in fifo order.
-		 * In fact, requests are seldom served in fifo order.
-		 *
-		 * Expire the queue for budget exhaustion, and make sure
-		 * that the next act_budget is enough to serve the next
-		 * request, even if it comes from the fifo expired path.
-		 */
-		bfqq->next_rq = rq;
-		/*
-		 * Since this dispatch is failed, make sure that
-		 * a new one will be performed
-		 */
-		if (!bfqd->rq_in_driver)
-			bfq_schedule_dispatch(bfqd);
-		BUG_ON(bfqq->entity.budget < bfqq->entity.service);
-		goto expire;
-	}
+	BUG_ON(service_to_charge > bfq_bfqq_budget_left(bfqq));

 	BUG_ON(bfqq->entity.budget < bfqq->entity.service);
-	/* Finally, insert request into driver dispatch list. */
+
 	bfq_bfqq_served(bfqq, service_to_charge);

 	BUG_ON(bfqq->entity.budget < bfqq->entity.service);
@@ -3805,7 +3833,8 @@ static int bfq_dispatch_requests(struct request_queue *q, int force)
  * Task holds one reference to the queue, dropped when task exits.  Each rq
  * in-flight on this queue also holds a reference, dropped when rq is freed.
  *
- * Queue lock must be held here.
+ * Queue lock must be held here. Recall not to use bfqq after calling
+ * this function on it.
  */
 static void bfq_put_queue(struct bfq_queue *bfqq)
 {
@@ -3874,7 +3903,7 @@ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)

 	bfq_put_cooperator(bfqq);

-	bfq_put_queue(bfqq);
+	bfq_put_queue(bfqq); /* release process reference */
 }

 static void bfq_init_icq(struct io_cq *icq)
@@ -3973,6 +4002,7 @@ static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio)

 	bfqq = bic_to_bfqq(bic, false);
 	if (bfqq) {
+		/* release process reference on this queue */
 		bfq_put_queue(bfqq);
 		bfqq = bfq_get_queue(bfqd, bio, BLK_RW_ASYNC, bic);
 		bic_set_bfqq(bic, bfqq, false);
@@ -4093,14 +4123,20 @@ static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
 	 * prune it.
 	 */
 	if (async_bfqq) {
-		bfqq->ref++;
+		bfqq->ref++; /*
+			      * Extra group reference, w.r.t. sync
+			      * queue. This extra reference is removed
+			      * only if bfqq->bfqg disappears, to
+			      * guarantee that this queue is not freed
+			      * until its group goes away.
+			      */
 		bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d",
 			     bfqq, bfqq->ref);
 		*async_bfqq = bfqq;
 	}

 out:
-	bfqq->ref++;
+	bfqq->ref++; /* get a process reference to this queue */
 	bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq, bfqq->ref);
 	rcu_read_unlock();
 	return bfqq;
@@ -4274,10 +4310,14 @@ static void bfq_insert_request(struct request_queue *q, struct request *rq)
 			bfqq->allocated[rq_data_dir(rq)]--;
 			new_bfqq->ref++;
 			bfq_clear_bfqq_just_created(bfqq);
-			bfq_put_queue(bfqq);
 			if (bic_to_bfqq(RQ_BIC(rq), 1) == bfqq)
 				bfq_merge_bfqqs(bfqd, RQ_BIC(rq),
 						bfqq, new_bfqq);
+			/*
+			 * rq is about to be enqueued into new_bfqq,
+			 * release rq reference on bfqq
+			 */
+			bfq_put_queue(bfqq);
 			rq->elv.priv[1] = new_bfqq;
 			bfqq = new_bfqq;
 		}
@@ -4697,9 +4737,8 @@ static void bfq_shutdown_timer_wq(struct bfq_data *bfqd)
 	cancel_work_sync(&bfqd->unplug_work);
 }

-#ifdef CONFIG_BFQ_GROUP_IOSCHED
 static void __bfq_put_async_bfqq(struct bfq_data *bfqd,
-					struct bfq_queue **bfqq_ptr)
+				 struct bfq_queue **bfqq_ptr)
 {
 	struct bfq_group *root_group = bfqd->root_group;
 	struct bfq_queue *bfqq = *bfqq_ptr;
@@ -4730,7 +4769,6 @@ static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg)

 	__bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq);
 }
-#endif

 static void bfq_exit_queue(struct elevator_queue *e)
 {
@@ -4755,6 +4793,7 @@ static void bfq_exit_queue(struct elevator_queue *e)
 #ifdef CONFIG_BFQ_GROUP_IOSCHED
 	blkcg_deactivate_policy(q, &blkcg_policy_bfq);
 #else
+	bfq_put_async_queues(bfqd, bfqd->root_group);
 	kfree(bfqd->root_group);
 #endif

@@ -5229,7 +5268,7 @@ static struct blkcg_policy blkcg_policy_bfq = {
 static int __init bfq_init(void)
 {
 	int ret;
-	char msg[60] = "BFQ I/O-scheduler: v8r7";
+	char msg[60] = "BFQ I/O-scheduler: v8r10";

 #ifdef CONFIG_BFQ_GROUP_IOSCHED
 	ret = blkcg_policy_register(&blkcg_policy_bfq);
@@ -5255,7 +5294,7 @@ static int __init bfq_init(void)
 	 * be run for a long time.
 	 */
 	T_slow[0] = msecs_to_jiffies(3500); /* actually 4 sec */
-	T_slow[1] = msecs_to_jiffies(1000); /* actually 1.5 sec */
+	T_slow[1] = msecs_to_jiffies(6000); /* actually 6.5 sec */
 	T_fast[0] = msecs_to_jiffies(7000); /* actually 8 sec */
 	T_fast[1] = msecs_to_jiffies(2500); /* actually 3 sec */

diff --git a/block/bfq-sched.c b/block/bfq-sched.c
index 797bce7..70aac56 100644
--- a/block/bfq-sched.c
+++ b/block/bfq-sched.c
@@ -154,7 +154,13 @@ static bool bfq_update_next_in_service(struct bfq_sched_data *sd,
 #define for_each_entity(entity)				\
 	for (; entity ; entity = entity->parent)

-#define for_each_entity_safe(entity, parent) \
+/*
+ * For each iteration, compute parent in advance, so as to be safe if
+ * entity is deallocated during the iteration. Such a deallocation may
+ * happen as a consequence of a bfq_put_queue that frees the bfq_queue
+ * containing entity.
+ */
+#define for_each_entity_safe(entity, parent)				\
 	for (; entity && ({ parent = entity->parent; 1; }); entity = parent)

 /*
@@ -691,27 +697,31 @@ static void bfq_idle_insert(struct bfq_service_tree *st,
 }

 /**
- * bfq_forget_entity - remove an entity from the wfq trees.
+ * bfq_forget_entity - do not consider entity any longer for scheduling
  * @st: the service tree.
  * @entity: the entity being removed.
+ * @is_in_service: true if entity is currently the in-service entity.
  *
- * Update the device status and forget everything about @entity, putting
- * the device reference to it, if it is a queue.  Entities belonging to
- * groups are not refcounted.
+ * Forget everything about @entity. In addition, if entity represents
+ * a queue, and the latter is not in service, then release the service
+ * reference to the queue (the one taken through bfq_get_entity). In
+ * fact, in this case, there is really no more service reference to
+ * the queue, as the latter is also outside any service tree. If,
+ * instead, the queue is in service, then __bfq_bfqd_reset_in_service
+ * will take care of putting the reference when the queue finally
+ * stops being served.
  */
 static void bfq_forget_entity(struct bfq_service_tree *st,
-			      struct bfq_entity *entity)
+			      struct bfq_entity *entity,
+			      bool is_in_service)
 {
 	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
-	struct bfq_sched_data *sd;
-
 	BUG_ON(!entity->on_st);

 	entity->on_st = false;
 	st->wsum -= entity->weight;
-	if (bfqq) {
-		sd = entity->sched_data;
-		bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d",
+	if (bfqq && !is_in_service) {
+		bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity (before): %p %d",
 			     bfqq, bfqq->ref);
 		bfq_put_queue(bfqq);
 	}
@@ -726,7 +736,8 @@ static void bfq_put_idle_entity(struct bfq_service_tree *st,
 				struct bfq_entity *entity)
 {
 	bfq_idle_extract(st, entity);
-	bfq_forget_entity(st, entity);
+	bfq_forget_entity(st, entity,
+			  entity == entity->sched_data->in_service_entity);
 }

 /**
@@ -1082,6 +1093,12 @@ static void __bfq_activate_entity(struct bfq_entity *entity,
 		 */
 		entity->start = min_vstart;
 		st->wsum += entity->weight;
+		/*
+		 * entity is about to be inserted into a service tree,
+		 * and then set in service: get a reference to make
+		 * sure entity does not disappear until it is no
+		 * longer in service or scheduled for service.
+		 */
 		bfq_get_entity(entity);

 		BUG_ON(entity->on_st && bfqq);
@@ -1264,27 +1281,27 @@ static bool __bfq_deactivate_entity(struct bfq_entity *entity,
 {
 	struct bfq_sched_data *sd = entity->sched_data;
 	struct bfq_service_tree *st = bfq_entity_service_tree(entity);
-	bool was_in_service = entity == sd->in_service_entity;
+	bool is_in_service = entity == sd->in_service_entity;

 	if (!entity->on_st) { /* entity never activated, or already inactive */
 		BUG_ON(entity == entity->sched_data->in_service_entity);
 		return false;
 	}

-	BUG_ON(was_in_service && entity->tree && entity->tree != &st->active);
+	BUG_ON(is_in_service && entity->tree && entity->tree != &st->active);

-	if (was_in_service)
+	if (is_in_service)
 		bfq_calc_finish(entity, entity->service);

 	if (entity->tree == &st->active)
 		bfq_active_extract(st, entity);
-	else if (!was_in_service && entity->tree == &st->idle)
+	else if (!is_in_service && entity->tree == &st->idle)
 		bfq_idle_extract(st, entity);
 	else if (entity->tree)
 		BUG();

 	if (!ins_into_idle_tree || !bfq_gt(entity->finish, st->vtime))
-		bfq_forget_entity(st, entity);
+		bfq_forget_entity(st, entity, is_in_service);
 	else
 		bfq_idle_insert(st, entity);

@@ -1301,7 +1318,7 @@ static void bfq_deactivate_entity(struct bfq_entity *entity,
 				  bool expiration)
 {
 	struct bfq_sched_data *sd;
-	struct bfq_entity *parent;
+	struct bfq_entity *parent = NULL;

 	for_each_entity_safe(entity, parent) {
 		sd = entity->sched_data;
@@ -1320,8 +1337,8 @@ static void bfq_deactivate_entity(struct bfq_entity *entity,

 		if (!__bfq_deactivate_entity(entity, ins_into_idle_tree)) {
 			/*
-			 * Entity is not any tree any more, so, this
-			 * deactivation is a no-op, and there is
+			 * entity is not in any tree any more, so
+			 * this deactivation is a no-op, and there is
 			 * nothing to change for upper-level entities
 			 * (in case of expiration, this can never
 			 * happen).
@@ -1821,14 +1838,16 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)

 static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
 {
-	struct bfq_entity *entity = &bfqd->in_service_queue->entity;
+	struct bfq_queue *in_serv_bfqq = bfqd->in_service_queue;
+	struct bfq_entity *in_serv_entity = &in_serv_bfqq->entity;
+	struct bfq_entity *entity = in_serv_entity;

 	if (bfqd->in_service_bic) {
 		put_io_context(bfqd->in_service_bic->icq.ioc);
 		bfqd->in_service_bic = NULL;
 	}

-	bfq_clear_bfqq_wait_request(bfqd->in_service_queue);
+	bfq_clear_bfqq_wait_request(in_serv_bfqq);
 	hrtimer_try_to_cancel(&bfqd->idle_slice_timer);
 	bfqd->in_service_queue = NULL;

@@ -1840,6 +1859,14 @@ static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
 	 */
 	for_each_entity(entity)
 		entity->sched_data->in_service_entity = NULL;
+
+	/*
+	 * in_serv_entity is no longer in service, so, if it is in no
+	 * service tree either, then release the service reference to
+	 * the queue it represents (taken with bfq_get_entity).
+	 */
+	if (!in_serv_entity->on_st)
+		bfq_put_queue(in_serv_bfqq);
 }

 static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
@@ -1904,8 +1931,6 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
 	BUG_ON(bfqq->entity.budget < 0);

 	bfq_deactivate_bfqq(bfqd, bfqq, true, expiration);
-
-	BUG_ON(bfqq->entity.budget < 0);
 }

 /*
diff --git a/block/bfq.h b/block/bfq.h
index a9da002..e3855af 100644
--- a/block/bfq.h
+++ b/block/bfq.h
@@ -1,5 +1,5 @@
 /*
- * BFQ v8r7 for 4.9.0: data structures and common functions prototypes.
+ * BFQ v8r10 for 4.9.0: data structures and common functions prototypes.
  *
  * Based on ideas and code from CFQ:
  * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
@@ -9,7 +9,7 @@
  *
  * Copyright (C) 2015 Paolo Valente <paolo.valente@unimore.it>
  *
- * Copyright (C) 2016 Paolo Valente <paolo.valente@linaro.org>
+ * Copyright (C) 2017 Paolo Valente <paolo.valente@linaro.org>
  */

 #ifndef _BFQ_H


code:
agp/intel: add new host bridge id for Q57 system

Add new Host Bridge ID found on a Q57 based system from Positivo. I
don't know what abbreviation id for this would be best, may be Q_HB
instead of UNKNOWN currently used would be better.

Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>

[ rebased for 3.8-rc3 /tmb ]
Signed-off-by: Thomas Backlund <tmb@mageia.org>

Removed the parts of the patch that are already applied in the kernel by
the commit 67384fe3fd450536342330f684ea1f7dcaef8130:
    "char/agp: add another Ironlake host bridge"

Rediffed for kernel 3.10.24.

Signed-off-by: Eugene A. Shatokhin <eugene.shatokhin@rosalab.ru>

 drivers/char/agp/intel-gtt.c |    2 ++
 1 file changed, 2 insertions(+)

diff -Nurp linux-3.8-rc3/drivers/char/agp/intel-gtt.c linux-3.8-rc3.q57/drivers/char/agp/intel-gtt.c
--- linux-3.8-rc3/drivers/char/agp/intel-gtt.c	2013-01-10 08:17:09.690594184 +0200
+++ linux-3.8-rc3.q57/drivers/char/agp/intel-gtt.c	2013-01-10 08:38:56.649888839 +0200
@@ -1303,6 +1303,8 @@ static const struct intel_gtt_driver_des
 		&g4x_gtt_driver },
 	{ PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG,
 	    "HD Graphics", &ironlake_gtt_driver },
+	{ PCI_DEVICE_ID_INTEL_IRONLAKE_D2_HB,
+	    "HD Graphics", &ironlake_gtt_driver },
 	{ PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG,
 	    "HD Graphics", &ironlake_gtt_driver },
 	{ 0, NULL, NULL }


code:
From bc33c5df710c0aae6db396146194108634ef6f60 Mon Sep 17 00:00:00 2001
From: "Winkler, Tomas" <tomas.winkler@intel.com>
Date: Mon, 12 Sep 2016 16:04:19 +0300
Subject: [PATCH] tmp/tpm_crb: fix Intel PTT hw bug during idle state

There is a HW bug in Skylake, and Broxton PCH Intel PTT device, where
most of the registers in the control area except START, REQUEST, CANCEL,
and LOC_CTRL lost retention when the device is in the idle state. Hence
we need to bring the device to ready state before accessing the other
registers. The fix brings device to ready state before trying to read
command and response buffer addresses in order to remap the for access.

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Tested-by: Jarkko Sakkinen <jarkko.sakkinn@linux.intel.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinn@linux.intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/tpm_crb.c | 47 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 39 insertions(+), 8 deletions(-)

diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index 8dd0f20..ff0d505 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -315,6 +315,7 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
 	struct list_head resources;
 	struct resource io_res;
 	struct device *dev = &device->dev;
+	u32 pa_high, pa_low;
 	u64 cmd_pa;
 	u32 cmd_size;
 	u64 rsp_pa;
@@ -342,12 +343,27 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
 	if (IS_ERR(priv->cca))
 		return PTR_ERR(priv->cca);

-	cmd_pa = ((u64) ioread32(&priv->cca->cmd_pa_high) << 32) |
-		  (u64) ioread32(&priv->cca->cmd_pa_low);
+	/*
+	 * PTT HW bug w/a: wake up the device to access
+	 * possibly not retained registers.
+	 */
+	ret = crb_cmd_ready(dev, priv);
+	if (ret)
+		return ret;
+
+	pa_high = ioread32(&priv->cca->cmd_pa_high);
+	pa_low  = ioread32(&priv->cca->cmd_pa_low);
+	cmd_pa = ((u64)pa_high << 32) | pa_low;
 	cmd_size = ioread32(&priv->cca->cmd_size);
+
+	dev_dbg(dev, "cmd_hi = %X cmd_low = %X cmd_size %X\n",
+		pa_high, pa_low, cmd_size);
+
 	priv->cmd = crb_map_res(dev, priv, &io_res, cmd_pa, cmd_size);
-	if (IS_ERR(priv->cmd))
-		return PTR_ERR(priv->cmd);
+	if (IS_ERR(priv->cmd)) {
+		ret = PTR_ERR(priv->cmd);
+		goto out;
+	}

 	memcpy_fromio(&rsp_pa, &priv->cca->rsp_pa, 8);
 	rsp_pa = le64_to_cpu(rsp_pa);
@@ -355,7 +371,8 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,

 	if (cmd_pa != rsp_pa) {
 		priv->rsp = crb_map_res(dev, priv, &io_res, rsp_pa, rsp_size);
-		return PTR_ERR_OR_ZERO(priv->rsp);
+		ret = PTR_ERR_OR_ZERO(priv->rsp);
+		goto out;
 	}

 	/* According to the PTP specification, overlapping command and response
@@ -363,12 +380,18 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
 	 */
 	if (cmd_size != rsp_size) {
 		dev_err(dev, FW_BUG "overlapping command and response buffer sizes are not identical");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
+
 	priv->cmd_size = cmd_size;

 	priv->rsp = priv->cmd;
-	return 0;
+
+out:
+	crb_go_idle(dev, priv);
+
+	return ret;
 }

 static int crb_acpi_add(struct acpi_device *device)
@@ -412,7 +435,15 @@ static int crb_acpi_add(struct acpi_device *device)
 	if (rc)
 		return rc;

-	return crb_init(device, priv);
+	rc  = crb_cmd_ready(dev, priv);
+	if (rc)
+		return rc;
+
+	rc = crb_init(device, priv);
+	if (rc)
+		crb_go_idle(dev, priv);
+
+	return rc;
 }

 static int crb_acpi_remove(struct acpi_device *device)
--
2.10.2


code:
From e74f2f76c13770bb8e004475a933923e9c92723d Mon Sep 17 00:00:00 2001
From: "Winkler, Tomas" <tomas.winkler@intel.com>
Date: Sat, 8 Oct 2016 14:59:39 +0300
Subject: [PATCH] tmp/tpm_crb: implement runtime pm for tpm_crb

Utilize runtime_pm for driving tpm crb idle states.
The framework calls cmd_ready from the pm_runtime_resume handler
and go idle from the pm_runtime_suspend handler.
The TPM framework should wake the device before transmit and receive.
In case the runtime_pm framework is not compiled in or enabled, the device
will be in the permanent ready state.

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/tpm-interface.c |  5 +++++
 drivers/char/tpm/tpm_crb.c       | 42 ++++++++++++++++++++++++++++++++++++----
 2 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 3a9149c..cb0e57e 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -29,6 +29,7 @@
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
 #include <linux/freezer.h>
+#include <linux/pm_runtime.h>

 #include "tpm.h"
 #include "tpm_eventlog.h"
@@ -356,6 +357,8 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
 	if (!(flags & TPM_TRANSMIT_UNLOCKED))
 		mutex_lock(&chip->tpm_mutex);

+	pm_runtime_get_sync(chip->dev.parent);
+
 	rc = chip->ops->send(chip, (u8 *) buf, count);
 	if (rc < 0) {
 		dev_err(&chip->dev,
@@ -397,6 +400,8 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
 		dev_err(&chip->dev,
 			"tpm_transmit: tpm_recv: error %zd\n", rc);
 out:
+	pm_runtime_put_sync(chip->dev.parent);
+
 	if (!(flags & TPM_TRANSMIT_UNLOCKED))
 		mutex_unlock(&chip->tpm_mutex);
 	return rc;
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index f579f1a..717b6b4 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -19,6 +19,7 @@
 #include <linux/highmem.h>
 #include <linux/rculist.h>
 #include <linux/module.h>
+#include <linux/pm_runtime.h>
 #include "tpm.h"

 #define ACPI_SIG_TPM2 "TPM2"
@@ -149,8 +150,6 @@ static int __maybe_unused crb_cmd_ready(struct device *dev,
 	return 0;
 }

-static SIMPLE_DEV_PM_OPS(crb_pm, tpm_pm_suspend, tpm_pm_resume);
-
 static u8 crb_status(struct tpm_chip *chip)
 {
 	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
@@ -433,11 +432,21 @@ static int crb_acpi_add(struct acpi_device *device)
 	if (rc)
 		return rc;

+	pm_runtime_get_noresume(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+
 	rc = tpm_chip_register(chip);
-	if (rc)
+	if (rc) {
 		crb_go_idle(dev, priv);
+		pm_runtime_put_noidle(dev);
+		pm_runtime_disable(dev);
+		return rc;
+	}

-	return rc;
+	pm_runtime_put(dev);
+
+	return 0;
 }

 static int crb_acpi_remove(struct acpi_device *device)
@@ -447,9 +456,34 @@ static int crb_acpi_remove(struct acpi_device *device)

 	tpm_chip_unregister(chip);

+	pm_runtime_disable(dev);
+
 	return 0;
 }

+#ifdef CONFIG_PM
+static int crb_pm_runtime_suspend(struct device *dev)
+{
+	struct tpm_chip *chip = dev_get_drvdata(dev);
+	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
+
+	return crb_go_idle(dev, priv);
+}
+
+static int crb_pm_runtime_resume(struct device *dev)
+{
+	struct tpm_chip *chip = dev_get_drvdata(dev);
+	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
+
+	return crb_cmd_ready(dev, priv);
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops crb_pm = {
+	SET_SYSTEM_SLEEP_PM_OPS(tpm_pm_suspend, tpm_pm_resume)
+	SET_RUNTIME_PM_OPS(crb_pm_runtime_suspend, crb_pm_runtime_resume, NULL)
+};
+
 static struct acpi_device_id crb_device_ids[] = {
 	{"MSFT0101", 0},
 	{"", 0},
--
2.10.2


code:
From ba5287b6ef6a2ee91dc6cc0829649cecf7b70253 Mon Sep 17 00:00:00 2001
From: "Winkler, Tomas" <tomas.winkler@intel.com>
Date: Thu, 15 Sep 2016 10:27:38 +0300
Subject: [PATCH] tpm/tpm_crb: implement tpm crb idle state

The register TPM_CRB_CTRL_REQ_x contains bits goIdle and cmdReady for
SW to indicate that the device can enter or should exit the idle state.

The legacy ACPI-start (SMI + DMA) based devices do not support these
bits and the idle state management is not exposed to the host SW.
Thus, this functionality only is enabled only for a CRB start (MMIO)
based devices.

Based on Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
original patch:
'tpm_crb: implement power tpm crb power management'

To keep the implementation local to the hw we don't use wait_for_tpm_stat
for polling the TPM_CRB_CTRL_REQ.

[jarkko.sakkinen@linux.intel.com: removed cmdReady debug trace on a
 success case due the heavy amount of log traffic it causes.]

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/tpm_crb.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index a7c870a..8dd0f20 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -83,6 +83,72 @@ struct crb_priv {
 	u32 cmd_size;
 };

+/**
+ * crb_go_idle - request tpm crb device to go the idle state
+ *
+ * @dev:  crb device
+ * @priv: crb private data
+ *
+ * Write CRB_CTRL_REQ_GO_IDLE to TPM_CRB_CTRL_REQ
+ * The device should respond within TIMEOUT_C by clearing the bit.
+ * Anyhow, we do not wait here as a consequent CMD_READY request
+ * will be handled correctly even if idle was not completed.
+ *
+ * The function does nothing for devices with ACPI-start method.
+ *
+ * Return: 0 always
+ */
+static int __maybe_unused crb_go_idle(struct device *dev, struct crb_priv *priv)
+{
+	if (priv->flags & CRB_FL_ACPI_START)
+		return 0;
+
+	iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->cca->req);
+	/* we don't really care when this settles */
+
+	return 0;
+}
+
+/**
+ * crb_cmd_ready - request tpm crb device to enter ready state
+ *
+ * @dev:  crb device
+ * @priv: crb private data
+ *
+ * Write CRB_CTRL_REQ_CMD_READY to TPM_CRB_CTRL_REQ
+ * and poll till the device acknowledge it by clearing the bit.
+ * The device should respond within TIMEOUT_C.
+ *
+ * The function does nothing for devices with ACPI-start method
+ *
+ * Return: 0 on success -ETIME on timeout;
+ */
+static int __maybe_unused crb_cmd_ready(struct device *dev,
+					struct crb_priv *priv)
+{
+	ktime_t stop, start;
+
+	if (priv->flags & CRB_FL_ACPI_START)
+		return 0;
+
+	iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->cca->req);
+
+	start = ktime_get();
+	stop = ktime_add(start, ms_to_ktime(TPM2_TIMEOUT_C));
+	do {
+		if (!(ioread32(&priv->cca->req) & CRB_CTRL_REQ_CMD_READY))
+			return 0;
+		usleep_range(50, 100);
+	} while (ktime_before(ktime_get(), stop));
+
+	if (ioread32(&priv->cca->req) & CRB_CTRL_REQ_CMD_READY) {
+		dev_warn(dev, "cmdReady timed out\n");
+		return -ETIME;
+	}
+
+	return 0;
+}
+
 static SIMPLE_DEV_PM_OPS(crb_pm, tpm_pm_suspend, tpm_pm_resume);

 static u8 crb_status(struct tpm_chip *chip)
--
2.10.2


code:
From c58bd34cec4c05f8e3362a79ae94de9f405c39b5 Mon Sep 17 00:00:00 2001
From: "Winkler, Tomas" <tomas.winkler@intel.com>
Date: Mon, 12 Sep 2016 16:04:20 +0300
Subject: [PATCH] tpm/tpm_crb: open code the crb_init into acpi_add

This is preparation step for implementing tpm crb
runtime pm. We need to have tpm chip allocated
and populated before we access the runtime handlers.

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/tpm_crb.c | 26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index ff0d505..f579f1a 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -262,21 +262,6 @@ static const struct tpm_class_ops tpm_crb = {
 	.req_complete_val = CRB_DRV_STS_COMPLETE,
 };

-static int crb_init(struct acpi_device *device, struct crb_priv *priv)
-{
-	struct tpm_chip *chip;
-
-	chip = tpmm_chip_alloc(&device->dev, &tpm_crb);
-	if (IS_ERR(chip))
-		return PTR_ERR(chip);
-
-	dev_set_drvdata(&chip->dev, priv);
-	chip->acpi_dev_handle = device->handle;
-	chip->flags = TPM_CHIP_FLAG_TPM2;
-
-	return tpm_chip_register(chip);
-}
-
 static int crb_check_resource(struct acpi_resource *ares, void *data)
 {
 	struct resource *io_res = data;
@@ -398,6 +383,7 @@ static int crb_acpi_add(struct acpi_device *device)
 {
 	struct acpi_table_tpm2 *buf;
 	struct crb_priv *priv;
+	struct tpm_chip *chip;
 	struct device *dev = &device->dev;
 	acpi_status status;
 	u32 sm;
@@ -435,11 +421,19 @@ static int crb_acpi_add(struct acpi_device *device)
 	if (rc)
 		return rc;

+	chip = tpmm_chip_alloc(dev, &tpm_crb);
+	if (IS_ERR(chip))
+		return PTR_ERR(chip);
+
+	dev_set_drvdata(&chip->dev, priv);
+	chip->acpi_dev_handle = device->handle;
+	chip->flags = TPM_CHIP_FLAG_TPM2;
+
 	rc  = crb_cmd_ready(dev, priv);
 	if (rc)
 		return rc;

-	rc = crb_init(device, priv);
+	rc = tpm_chip_register(chip);
 	if (rc)
 		crb_go_idle(dev, priv);

--
2.10.2


code:
This patch adds module aliases for matching the old dm-raid45 patch
by heinzm@redhat.com carried by kernel-tmb series in order to make
sure there is an upgrade path.

Signed-off-by: Thomas Backlund <tmb@mageia.org>

 drivers/md/dm-raid.c |    2 ++
 1 file changed, 2 insertions(+)

--- linux/drivers/md/dm-raid.c.orig
+++ linux/drivers/md/dm-raid.c
@@ -3689,6 +3689,8 @@ MODULE_ALIAS("dm-raid10");
 MODULE_ALIAS("dm-raid4");
 MODULE_ALIAS("dm-raid5");
 MODULE_ALIAS("dm-raid6");
+MODULE_ALIAS("dm-raid45");
+MODULE_ALIAS("dm-raid4-5");
 MODULE_AUTHOR("Neil Brown <dm-devel@redhat.com>");
 MODULE_AUTHOR("Heinz Mauelshagen <dm-devel@redhat.com>");
 MODULE_LICENSE("GPL");


code:
This patch adds missing module aliases for the old ieee1394 stack
to make it easier for endusers.

Note: firewire-sbp2 and firewire-ohci already contains the needed aliases.

Signed-off-by: Thomas Backlund <tmb@mageia.org>

diff -Nurp linux-2.6.38.4/drivers/firewire/core-transaction.c linux-2.6.38.4.fw/drivers/firewire/core-transaction.c
--- linux-2.6.38.4/drivers/firewire/core-transaction.c	2011-03-15 03:20:32.000000000 +0200
+++ linux-2.6.38.4.fw/drivers/firewire/core-transaction.c	2011-04-22 16:22:28.461386738 +0300
@@ -1174,6 +1174,9 @@ static struct fw_address_handler registe
 MODULE_AUTHOR("Kristian Hoegsberg <krh@bitplanet.net>");
 MODULE_DESCRIPTION("Core IEEE1394 transaction logic");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("ieee1394");
+MODULE_ALIAS("raw1394");
+MODULE_ALIAS("video1394");

 static const u32 vendor_textual_descriptor[] = {
 	/* textual descriptor leaf () */
diff -Nurp linux-2.6.38.4/drivers/firewire/net.c linux-2.6.38.4.fw/drivers/firewire/net.c
--- linux-2.6.38.4/drivers/firewire/net.c	2011-03-15 03:20:32.000000000 +0200
+++ linux-2.6.38.4.fw/drivers/firewire/net.c	2011-04-22 16:20:34.008883920 +0300
@@ -1719,3 +1719,4 @@ MODULE_AUTHOR("Jay Fenlason <fenlason@re
 MODULE_DESCRIPTION("IP over IEEE1394 as per RFC 2734/3146");
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(ieee1394, fwnet_id_table);
+MODULE_ALIAS("eth1394");


code:
 fs/aufs/Kconfig          |    2 +-
 fs/dcache.c              |    2 ++
 fs/exec.c                |    1 +
 fs/fcntl.c               |    1 +
 fs/file_table.c          |    4 ++++
 fs/inode.c               |    1 +
 fs/namespace.c           |    2 ++
 fs/notify/group.c        |    4 ++++
 fs/notify/mark.c         |    4 ++++
 fs/open.c                |    2 ++
 fs/read_write.c          |    2 ++
 fs/splice.c              |    2 ++
 fs/xattr.c               |    1 +
 kernel/task_work.c       |    1 +
 security/commoncap.c     |    2 ++
 security/device_cgroup.c |    2 ++
 security/security.c      |   10 ++++++++++
 17 files changed, 42 insertions(+), 1 deletion(-)

diff -Nurp linux-4.9-aufs/fs/aufs/Kconfig linux-4.9-aufs-mod/fs/aufs/Kconfig
--- linux-4.9-aufs/fs/aufs/Kconfig	2016-12-31 00:31:52.367789380 +0200
+++ linux-4.9-aufs-mod/fs/aufs/Kconfig	2016-12-31 00:32:35.153785422 +0200
@@ -1,5 +1,5 @@
 config AUFS_FS
-	bool "Aufs (Advanced multi layered unification filesystem) support"
+	tristate "Aufs (Advanced multi layered unification filesystem) support"
 	help
 	Aufs is a stackable unification filesystem such as Unionfs,
 	which unifies several directories and provides a merged single
diff -Nurp linux-4.9-aufs/fs/dcache.c linux-4.9-aufs-mod/fs/dcache.c
--- linux-4.9-aufs/fs/dcache.c	2016-12-31 00:31:52.379789379 +0200
+++ linux-4.9-aufs-mod/fs/dcache.c	2016-12-31 01:49:12.324360147 +0200
@@ -1272,6 +1272,7 @@ rename_retry:
 	seq = 1;
 	goto again;
 }
+EXPORT_SYMBOL_GPL(d_walk);

 /*
  * Search for at least 1 mount point in the dentry's subdirs.
@@ -2855,6 +2856,7 @@ void d_exchange(struct dentry *dentry1,

 	write_sequnlock(&rename_lock);
 }
+EXPORT_SYMBOL_GPL(d_exchange);

 /**
  * d_ancestor - search for an ancestor
diff -Nurp linux-4.9-aufs/fs/exec.c linux-4.9-aufs-mod/fs/exec.c
--- linux-4.9-aufs/fs/exec.c	2016-12-11 21:17:54.000000000 +0200
+++ linux-4.9-aufs-mod/fs/exec.c	2016-12-31 00:32:35.153785422 +0200
@@ -104,6 +104,7 @@ bool path_noexec(const struct path *path
 	return (path->mnt->mnt_flags & MNT_NOEXEC) ||
 	       (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
 }
+EXPORT_SYMBOL_GPL(path_noexec);

 #ifdef CONFIG_USELIB
 /*
diff -Nurp linux-4.9-aufs/fs/fcntl.c linux-4.9-aufs-mod/fs/fcntl.c
--- linux-4.9-aufs/fs/fcntl.c	2016-12-31 00:31:52.379789379 +0200
+++ linux-4.9-aufs-mod/fs/fcntl.c	2016-12-31 00:32:35.154785422 +0200
@@ -82,6 +82,7 @@ int setfl(int fd, struct file * filp, un
  out:
 	return error;
 }
+EXPORT_SYMBOL_GPL(setfl);

 static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
                      int force)
diff -Nurp linux-4.9-aufs/fs/file_table.c linux-4.9-aufs-mod/fs/file_table.c
--- linux-4.9-aufs/fs/file_table.c	2016-12-11 21:17:54.000000000 +0200
+++ linux-4.9-aufs-mod/fs/file_table.c	2016-12-31 00:32:35.154785422 +0200
@@ -147,6 +147,7 @@ over:
 	}
 	return ERR_PTR(-ENFILE);
 }
+EXPORT_SYMBOL_GPL(get_empty_filp);

 /**
  * alloc_file - allocate and initialize a 'struct file'
@@ -258,6 +259,7 @@ void flush_delayed_fput(void)
 {
 	delayed_fput(NULL);
 }
+EXPORT_SYMBOL_GPL(flush_delayed_fput);

 static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput);

@@ -300,6 +302,7 @@ void __fput_sync(struct file *file)
 }

 EXPORT_SYMBOL(fput);
+EXPORT_SYMBOL_GPL(__fput_sync);

 void put_filp(struct file *file)
 {
@@ -308,6 +311,7 @@ void put_filp(struct file *file)
 		file_free(file);
 	}
 }
+EXPORT_SYMBOL_GPL(put_filp);

 void __init files_init(void)
 {
diff -Nurp linux-4.9-aufs/fs/inode.c linux-4.9-aufs-mod/fs/inode.c
--- linux-4.9-aufs/fs/inode.c	2016-12-31 00:31:52.379789379 +0200
+++ linux-4.9-aufs-mod/fs/inode.c	2016-12-31 00:32:35.154785422 +0200
@@ -1651,6 +1651,7 @@ int update_time(struct inode *inode, str

 	return update_time(inode, time, flags);
 }
+EXPORT_SYMBOL_GPL(update_time);

 /**
  *	touch_atime	-	update the access time
diff -Nurp linux-4.9-aufs/fs/namespace.c linux-4.9-aufs-mod/fs/namespace.c
--- linux-4.9-aufs/fs/namespace.c	2016-12-11 21:17:54.000000000 +0200
+++ linux-4.9-aufs-mod/fs/namespace.c	2016-12-31 00:32:35.154785422 +0200
@@ -466,6 +466,7 @@ void __mnt_drop_write(struct vfsmount *m
 	mnt_dec_writers(real_mount(mnt));
 	preempt_enable();
 }
+EXPORT_SYMBOL_GPL(__mnt_drop_write);

 /**
  * mnt_drop_write - give up write access to a mount
@@ -1823,6 +1824,7 @@ int iterate_mounts(int (*f)(struct vfsmo
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(iterate_mounts);

 static void cleanup_group_ids(struct mount *mnt, struct mount *end)
 {
diff -Nurp linux-4.9-aufs/fs/notify/group.c linux-4.9-aufs-mod/fs/notify/group.c
--- linux-4.9-aufs/fs/notify/group.c	2016-12-11 21:17:54.000000000 +0200
+++ linux-4.9-aufs-mod/fs/notify/group.c	2016-12-31 00:32:35.155785422 +0200
@@ -22,6 +22,7 @@
 #include <linux/srcu.h>
 #include <linux/rculist.h>
 #include <linux/wait.h>
+#include <linux/module.h>

 #include <linux/fsnotify_backend.h>
 #include "fsnotify.h"
@@ -100,6 +101,7 @@ void fsnotify_get_group(struct fsnotify_
 {
 	atomic_inc(&group->refcnt);
 }
+EXPORT_SYMBOL_GPL(fsnotify_get_group);

 /*
  * Drop a reference to a group.  Free it if it's through.
@@ -109,6 +111,7 @@ void fsnotify_put_group(struct fsnotify_
 	if (atomic_dec_and_test(&group->refcnt))
 		fsnotify_final_destroy_group(group);
 }
+EXPORT_SYMBOL_GPL(fsnotify_put_group);

 /*
  * Create a new fsnotify_group and hold a reference for the group returned.
@@ -137,6 +140,7 @@ struct fsnotify_group *fsnotify_alloc_gr

 	return group;
 }
+EXPORT_SYMBOL_GPL(fsnotify_alloc_group);

 int fsnotify_fasync(int fd, struct file *file, int on)
 {
diff -Nurp linux-4.9-aufs/fs/notify/mark.c linux-4.9-aufs-mod/fs/notify/mark.c
--- linux-4.9-aufs/fs/notify/mark.c	2016-12-11 21:17:54.000000000 +0200
+++ linux-4.9-aufs-mod/fs/notify/mark.c	2016-12-31 00:32:35.155785422 +0200
@@ -113,6 +113,7 @@ void fsnotify_put_mark(struct fsnotify_m
 		mark->free_mark(mark);
 	}
 }
+EXPORT_SYMBOL_GPL(fsnotify_put_mark);

 /* Calculate mask of events for a list of marks */
 u32 fsnotify_recalc_mask(struct hlist_head *head)
@@ -230,6 +231,7 @@ void fsnotify_destroy_mark(struct fsnoti
 	mutex_unlock(&group->mark_mutex);
 	fsnotify_free_mark(mark);
 }
+EXPORT_SYMBOL_GPL(fsnotify_destroy_mark);

 void fsnotify_destroy_marks(struct hlist_head *head, spinlock_t *lock)
 {
@@ -415,6 +417,7 @@ err:

 	return ret;
 }
+EXPORT_SYMBOL_GPL(fsnotify_add_mark);

 int fsnotify_add_mark(struct fsnotify_mark *mark, struct fsnotify_group *group,
 		      struct inode *inode, struct vfsmount *mnt, int allow_dups)
@@ -521,6 +524,7 @@ void fsnotify_duplicate_mark(struct fsno
 	new->mask = old->mask;
 	new->free_mark = old->free_mark;
 }
+EXPORT_SYMBOL_GPL(fsnotify_init_mark);

 /*
  * Nothing fancy, just initialize lists and locks and counters.
diff -Nurp linux-4.9-aufs/fs/open.c linux-4.9-aufs-mod/fs/open.c
--- linux-4.9-aufs/fs/open.c	2016-12-11 21:17:54.000000000 +0200
+++ linux-4.9-aufs-mod/fs/open.c	2016-12-31 00:32:35.155785422 +0200
@@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, l
 	inode_unlock(dentry->d_inode);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(do_truncate);

 long vfs_truncate(const struct path *path, loff_t length)
 {
@@ -695,6 +696,7 @@ int open_check_o_direct(struct file *f)
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(open_check_o_direct);

 static int do_dentry_open(struct file *f,
 			  struct inode *inode,
diff -Nurp linux-4.9-aufs/fs/read_write.c linux-4.9-aufs-mod/fs/read_write.c
--- linux-4.9-aufs/fs/read_write.c	2016-12-31 00:31:52.380789379 +0200
+++ linux-4.9-aufs-mod/fs/read_write.c	2016-12-31 00:32:35.155785422 +0200
@@ -525,6 +525,7 @@ vfs_readf_t vfs_readf(struct file *file)
 		return new_sync_read;
 	return ERR_PTR(-ENOSYS);
 }
+EXPORT_SYMBOL_GPL(vfs_readf);

 vfs_writef_t vfs_writef(struct file *file)
 {
@@ -536,6 +537,7 @@ vfs_writef_t vfs_writef(struct file *fil
 		return new_sync_write;
 	return ERR_PTR(-ENOSYS);
 }
+EXPORT_SYMBOL_GPL(vfs_writef);

 ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
 {
diff -Nurp linux-4.9-aufs/fs/splice.c linux-4.9-aufs-mod/fs/splice.c
--- linux-4.9-aufs/fs/splice.c	2016-12-31 00:31:52.380789379 +0200
+++ linux-4.9-aufs-mod/fs/splice.c	2016-12-31 00:32:35.156785422 +0200
@@ -868,6 +868,7 @@ long do_splice_from(struct pipe_inode_in

 	return splice_write(pipe, out, ppos, len, flags);
 }
+EXPORT_SYMBOL_GPL(do_splice_from);

 /*
  * Attempt to initiate a splice from a file to a pipe.
@@ -897,6 +898,7 @@ long do_splice_to(struct file *in, loff_

 	return splice_read(in, ppos, pipe, len, flags);
 }
+EXPORT_SYMBOL_GPL(do_splice_to);

 /**
  * splice_direct_to_actor - splices data directly between two non-pipes
diff -Nurp linux-4.9-aufs/fs/xattr.c linux-4.9-aufs-mod/fs/xattr.c
--- linux-4.9-aufs/fs/xattr.c	2016-12-11 21:17:54.000000000 +0200
+++ linux-4.9-aufs-mod/fs/xattr.c	2016-12-31 00:32:35.156785422 +0200
@@ -296,6 +296,7 @@ vfs_getxattr_alloc(struct dentry *dentry
 	*xattr_value = value;
 	return error;
 }
+EXPORT_SYMBOL_GPL(vfs_getxattr_alloc);

 ssize_t
 __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
diff -Nurp linux-4.9-aufs/kernel/task_work.c linux-4.9-aufs-mod/kernel/task_work.c
--- linux-4.9-aufs/kernel/task_work.c	2016-12-11 21:17:54.000000000 +0200
+++ linux-4.9-aufs-mod/kernel/task_work.c	2016-12-31 00:32:35.156785422 +0200
@@ -119,3 +119,4 @@ void task_work_run(void)
 		} while (work);
 	}
 }
+EXPORT_SYMBOL_GPL(task_work_run);
diff -Nurp linux-4.9-aufs/security/commoncap.c linux-4.9-aufs-mod/security/commoncap.c
--- linux-4.9-aufs/security/commoncap.c	2016-12-11 21:17:54.000000000 +0200
+++ linux-4.9-aufs-mod/security/commoncap.c	2016-12-31 00:32:35.156785422 +0200
@@ -1061,12 +1061,14 @@ int cap_mmap_addr(unsigned long addr)
 	}
 	return ret;
 }
+EXPORT_SYMBOL_GPL(cap_mmap_addr);

 int cap_mmap_file(struct file *file, unsigned long reqprot,
 		  unsigned long prot, unsigned long flags)
 {
 	return 0;
 }
+EXPORT_SYMBOL_GPL(cap_mmap_file);

 #ifdef CONFIG_SECURITY

diff -Nurp linux-4.9-aufs/security/device_cgroup.c linux-4.9-aufs-mod/security/device_cgroup.c
--- linux-4.9-aufs/security/device_cgroup.c	2016-12-11 21:17:54.000000000 +0200
+++ linux-4.9-aufs-mod/security/device_cgroup.c	2016-12-31 00:32:35.156785422 +0200
@@ -7,6 +7,7 @@
 #include <linux/device_cgroup.h>
 #include <linux/cgroup.h>
 #include <linux/ctype.h>
+#include <linux/export.h>
 #include <linux/list.h>
 #include <linux/uaccess.h>
 #include <linux/seq_file.h>
@@ -849,6 +850,7 @@ int __devcgroup_inode_permission(struct
 	return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
 			access);
 }
+EXPORT_SYMBOL_GPL(__devcgroup_inode_permission);

 int devcgroup_inode_mknod(int mode, dev_t dev)
 {
diff -Nurp linux-4.9-aufs/security/security.c linux-4.9-aufs-mod/security/security.c
--- linux-4.9-aufs/security/security.c	2016-12-11 21:17:54.000000000 +0200
+++ linux-4.9-aufs-mod/security/security.c	2016-12-31 00:32:35.157785422 +0200
@@ -443,6 +443,7 @@ int security_path_rmdir(const struct pat
 		return 0;
 	return call_int_hook(path_rmdir, 0, dir, dentry);
 }
+EXPORT_SYMBOL_GPL(security_path_rmdir);

 int security_path_unlink(const struct path *dir, struct dentry *dentry)
 {
@@ -459,6 +460,7 @@ int security_path_symlink(const struct p
 		return 0;
 	return call_int_hook(path_symlink, 0, dir, dentry, old_name);
 }
+EXPORT_SYMBOL_GPL(security_path_symlink);

 int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
 		       struct dentry *new_dentry)
@@ -467,6 +469,7 @@ int security_path_link(struct dentry *ol
 		return 0;
 	return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
 }
+EXPORT_SYMBOL_GPL(security_path_link);

 int security_path_rename(const struct path *old_dir, struct dentry *old_dentry,
 			 const struct path *new_dir, struct dentry *new_dentry,
@@ -494,6 +497,7 @@ int security_path_truncate(const struct
 		return 0;
 	return call_int_hook(path_truncate, 0, path);
 }
+EXPORT_SYMBOL_GPL(security_path_truncate);

 int security_path_chmod(const struct path *path, umode_t mode)
 {
@@ -501,6 +505,7 @@ int security_path_chmod(const struct pat
 		return 0;
 	return call_int_hook(path_chmod, 0, path, mode);
 }
+EXPORT_SYMBOL_GPL(security_path_chmod);

 int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
 {
@@ -508,6 +513,7 @@ int security_path_chown(const struct pat
 		return 0;
 	return call_int_hook(path_chown, 0, path, uid, gid);
 }
+EXPORT_SYMBOL_GPL(security_path_chown);

 int security_path_chroot(const struct path *path)
 {
@@ -593,6 +599,7 @@ int security_inode_readlink(struct dentr
 		return 0;
 	return call_int_hook(inode_readlink, 0, dentry);
 }
+EXPORT_SYMBOL_GPL(security_inode_readlink);

 int security_inode_follow_link(struct dentry *dentry, struct inode *inode,
 			       bool rcu)
@@ -608,6 +615,7 @@ int security_inode_permission(struct ino
 		return 0;
 	return call_int_hook(inode_permission, 0, inode, mask);
 }
+EXPORT_SYMBOL_GPL(security_inode_permission);

 int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
 {
@@ -779,6 +787,7 @@ int security_file_permission(struct file

 	return fsnotify_perm(file, mask);
 }
+EXPORT_SYMBOL_GPL(security_file_permission);

 int security_file_alloc(struct file *file)
 {
@@ -838,6 +847,7 @@ int security_mmap_file(struct file *file
 		return ret;
 	return ima_file_mmap(file, prot);
 }
+EXPORT_SYMBOL_GPL(security_mmap_file);

 int security_mmap_addr(unsigned long addr)
 {