diff --git a/kernel/tools/cpupowertools/files/patches/fs-aufs-4.9-posix_acl.patch b/kernel/tools/cpupowertools/files/patches/fs-aufs-4.9-posix_acl.patch
new file mode 100644
index 00000000..29385a99
--- /dev/null
+++ b/kernel/tools/cpupowertools/files/patches/fs-aufs-4.9-posix_acl.patch
@@ -0,0 +1,86 @@
+diff -Nuar linux-4.9.orig/fs/aufs/posix_acl.c linux-4.9/fs/aufs/posix_acl.c
+--- linux-4.9.orig/fs/aufs/posix_acl.c 2017-04-09 09:33:00.155052337 +0300
++++ linux-4.9/fs/aufs/posix_acl.c 2017-04-09 09:34:03.760053849 +0300
+@@ -1,5 +1,18 @@
+ /*
+ * Copyright (C) 2014-2016 Junjiro R. Okajima
++ *
++ * This program, aufs is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program. If not, see .
+ */
+
+ /*
+@@ -36,6 +49,8 @@
+
+ /* always topmost only */
+ acl = get_acl(h_inode, type);
++ if (!IS_ERR_OR_NULL(acl))
++ set_cached_acl(inode, type, acl);
+
+ out:
+ ii_read_unlock(inode);
+@@ -77,8 +92,10 @@
+ ssz = au_sxattr(dentry, inode, &arg);
+ dput(dentry);
+ err = ssz;
+- if (ssz >= 0)
++ if (ssz >= 0) {
+ err = 0;
++ set_cached_acl(inode, type, acl);
++ }
+
+ out:
+ return err;
+diff -Nuar linux-4.9.orig/fs/aufs/xattr.c linux-4.9/fs/aufs/xattr.c
+--- linux-4.9.orig/fs/aufs/xattr.c 2017-04-09 09:33:00.160052337 +0300
++++ linux-4.9/fs/aufs/xattr.c 2017-04-09 09:34:08.757053967 +0300
+@@ -1,11 +1,26 @@
+ /*
+ * Copyright (C) 2014-2016 Junjiro R. Okajima
++ *
++ * This program, aufs is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program. If not, see .
+ */
+
+ /*
+ * handling xattr functions
+ */
+
++#include
++#include
+ #include
+ #include "aufs.h"
+
+@@ -309,7 +324,11 @@
+ };
+
+ static const struct xattr_handler *au_xattr_handlers[] = {
+- &au_xattr_handler,
++#ifdef CONFIG_FS_POSIX_ACL
++ &posix_acl_access_xattr_handler,
++ &posix_acl_default_xattr_handler,
++#endif
++ &au_xattr_handler, /* must be last */
+ NULL
+ };
+
diff --git a/kernel/tools/cpupowertools/files/patches/linux/patch-4.9.27.xz b/kernel/tools/cpupowertools/files/patches/linux/patch-4.9.27.xz
new file mode 100644
index 00000000..77b144dc
Binary files /dev/null and b/kernel/tools/cpupowertools/files/patches/linux/patch-4.9.27.xz differ
diff --git a/kernel/tools/cpupowertools/files/patches/mageia/block-Turn-into-BFQ-v8r6-for-4.9.0.patch b/kernel/tools/cpupowertools/files/patches/mageia/block-Turn-into-BFQ-v8r7-for-4.9.0.patch
similarity index 99%
rename from kernel/tools/cpupowertools/files/patches/mageia/block-Turn-into-BFQ-v8r6-for-4.9.0.patch
rename to kernel/tools/cpupowertools/files/patches/mageia/block-Turn-into-BFQ-v8r7-for-4.9.0.patch
index bd1279b5..5a5307fa 100644
--- a/kernel/tools/cpupowertools/files/patches/mageia/block-Turn-into-BFQ-v8r6-for-4.9.0.patch
+++ b/kernel/tools/cpupowertools/files/patches/mageia/block-Turn-into-BFQ-v8r7-for-4.9.0.patch
@@ -1,9 +1,13 @@
-From 3e3791c0b4ef3b2067f8454e58001af8e3da3840 Mon Sep 17 00:00:00 2001
+From 0432a5c7bfc4a11531c1e58f574c733a2552f149 Mon Sep 17 00:00:00 2001
From: Paolo Valente
Date: Tue, 17 May 2016 08:28:04 +0200
-Subject: [PATCH 4/4] Turn into BFQ-v8r6 for 4.9.0
+Subject: [PATCH 4/4] Turn into BFQ-v8r7 for 4.9.0
-CHANGELOG from v8r4 to v8r6
+CHANGELOG from v8r4 to v8r7
+
+BFQ v8r7
+
+BUGFIX: make BFQ compile also without hierarchical support
BFQ v8r6
@@ -125,9 +129,9 @@ Signed-off-by: Paolo Valente
block/Kconfig.iosched | 18 +-
block/bfq-cgroup.c | 501 +++---
block/bfq-iosched.c | 3278 ++++++++++++++++++++++-------------
- block/bfq-sched.c | 1270 +++++++++++---
+ block/bfq-sched.c | 1288 +++++++++++---
block/bfq.h | 800 +++++----
- 7 files changed, 4310 insertions(+), 2089 deletions(-)
+ 7 files changed, 4320 insertions(+), 2097 deletions(-)
create mode 100644 Documentation/block/bfq-iosched.txt
diff --git a/Documentation/block/00-INDEX b/Documentation/block/00-INDEX
@@ -1601,7 +1605,7 @@ index 0367996..bbaecd0 100644
static struct bfq_group *
diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
-index cf3e9b1..0f9cd53 100644
+index cf3e9b1..2a2c130 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -1,5 +1,5 @@
@@ -6201,7 +6205,7 @@ index cf3e9b1..0f9cd53 100644
-
- if (bfq_timeout_async == 0)
- bfq_timeout_async = 1;
-+ char msg[60] = "BFQ I/O-scheduler: v8r6";
++ char msg[60] = "BFQ I/O-scheduler: v8r7";
#ifdef CONFIG_BFQ_GROUP_IOSCHED
ret = blkcg_policy_register(&blkcg_policy_bfq);
@@ -6265,10 +6269,10 @@ index cf3e9b1..0f9cd53 100644
return 0;
diff --git a/block/bfq-sched.c b/block/bfq-sched.c
-index a5ed694..4af77f4 100644
+index a5ed694..797bce7 100644
--- a/block/bfq-sched.c
+++ b/block/bfq-sched.c
-@@ -7,28 +7,46 @@
+@@ -7,28 +7,166 @@
* Copyright (C) 2008 Fabio Checconi
* Paolo Valente
*
@@ -6276,8 +6280,8 @@ index a5ed694..4af77f4 100644
+ * Copyright (C) 2015 Paolo Valente
+ *
+ * Copyright (C) 2016 Paolo Valente
- */
-
++ */
++
+static struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
+
+/**
@@ -6292,63 +6296,17 @@ index a5ed694..4af77f4 100644
+ return (s64)(a - b) > 0;
+}
+
- #ifdef CONFIG_BFQ_GROUP_IOSCHED
--#define for_each_entity(entity) \
-+/* both next loops stop at one of the child entities of the root group */
-+#define for_each_entity(entity) \
- for (; entity ; entity = entity->parent)
-
- #define for_each_entity_safe(entity, parent) \
- for (; entity && ({ parent = entity->parent; 1; }); entity = parent)
-
-
--static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
-- int extract,
-- struct bfq_data *bfqd);
--
--static struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
-+static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd);
-
--static void bfq_update_budget(struct bfq_entity *next_in_service)
-+/*
-+ * Returns true if this budget changes may let next_in_service->parent
-+ * become the next_in_service entity for its parent entity.
-+ */
-+static bool bfq_update_parent_budget(struct bfq_entity *next_in_service)
- {
- struct bfq_entity *bfqg_entity;
- struct bfq_group *bfqg;
- struct bfq_sched_data *group_sd;
-+ bool ret = false;
-
- BUG_ON(!next_in_service);
-
-@@ -41,39 +59,134 @@ static void bfq_update_budget(struct bfq_entity *next_in_service)
- * as it must never become an in-service entity.
- */
- bfqg_entity = bfqg->my_entity;
-- if (bfqg_entity)
-+ if (bfqg_entity) {
-+ if (bfqg_entity->budget > next_in_service->budget)
-+ ret = true;
- bfqg_entity->budget = next_in_service->budget;
-+ }
-+
-+ return ret;
- }
-
--static int bfq_update_next_in_service(struct bfq_sched_data *sd)
+static struct bfq_entity *bfq_root_active_entity(struct rb_root *tree)
- {
-- struct bfq_entity *next_in_service;
++{
+ struct rb_node *node = tree->rb_node;
-
-- if (sd->in_service_entity)
-- /* will update/requeue at the end of service */
-- return 0;
++
+ return rb_entry(node, struct bfq_entity, rb_node);
+}
+
++static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd);
++
++static bool bfq_update_parent_budget(struct bfq_entity *next_in_service);
++
+/**
+ * bfq_update_next_in_service - update sd->next_in_service
+ * @sd: sched_data for which to perform the update.
@@ -6371,20 +6329,15 @@ index a5ed694..4af77f4 100644
+ * Returns true if sd->next_in_service changes in such a way that
+ * entity->parent may become the next_in_service for its parent
+ * entity.
-+ */
+ */
+static bool bfq_update_next_in_service(struct bfq_sched_data *sd,
+ struct bfq_entity *new_entity)
+{
+ struct bfq_entity *next_in_service = sd->next_in_service;
+ struct bfq_queue *bfqq;
+ bool parent_sched_may_change = false;
-
- /*
-- * NOTE: this can be improved in many ways, such as returning
-- * 1 (and thus propagating upwards the update) only when the
-- * budget changes, or caching the bfqq that will be scheduled
-- * next from this subtree. By now we worry more about
-- * correctness than about performance...
++
++ /*
+ * If this update is triggered by the activation, requeueing
+ * or repositiong of an entity that does not coincide with
+ * sd->next_in_service, then a full lookup in the active tree
@@ -6395,8 +6348,7 @@ index a5ed694..4af77f4 100644
+ * finish time than sd->next_in_service. If this compound
+ * condition holds, then the new entity becomes the new
+ * next_in_service. Otherwise no change is needed.
- */
-- next_in_service = bfq_lookup_next_entity(sd, 0, NULL);
++ */
+ if (new_entity && new_entity != sd->next_in_service) {
+ /*
+ * Flag used to decide whether to replace
@@ -6445,54 +6397,160 @@ index a5ed694..4af77f4 100644
+ bfq_update_parent_budget(next_in_service);
+ }
+
- sd->next_in_service = next_in_service;
-
-- if (next_in_service)
-- bfq_update_budget(next_in_service);
++ sd->next_in_service = next_in_service;
++
+ if (!next_in_service)
+ return parent_sched_may_change;
-- return 1;
--}
+ bfqq = bfq_entity_to_bfqq(next_in_service);
+ if (bfqq)
+ bfq_log_bfqq(bfqq->bfqd, bfqq,
+ "update_next_in_service: chosen this queue");
-+#ifdef CONFIG_BFQ_GROUP_IOSCHED
+ #ifdef CONFIG_BFQ_GROUP_IOSCHED
+-#define for_each_entity(entity) \
+ else {
+ struct bfq_group *bfqg =
+ container_of(next_in_service,
+ struct bfq_group, entity);
-
--static void bfq_check_next_in_service(struct bfq_sched_data *sd,
-- struct bfq_entity *entity)
--{
-- BUG_ON(sd->next_in_service != entity);
++
+ bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg,
+ "update_next_in_service: chosen this entity");
+ }
+#endif
+ return parent_sched_may_change;
- }
++}
+
- #else
- #define for_each_entity(entity) \
- for (; entity ; entity = NULL)
-@@ -86,12 +199,7 @@ static int bfq_update_next_in_service(struct bfq_sched_data *sd)
- return 0;
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++/* both next loops stop at one of the child entities of the root group */
++#define for_each_entity(entity) \
+ for (; entity ; entity = entity->parent)
+
+ #define for_each_entity_safe(entity, parent) \
+ for (; entity && ({ parent = entity->parent; 1; }); entity = parent)
+
+-
+-static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
+- int extract,
+- struct bfq_data *bfqd);
+-
+-static struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
+-
+-static void bfq_update_budget(struct bfq_entity *next_in_service)
++/*
++ * Returns true if this budget changes may let next_in_service->parent
++ * become the next_in_service entity for its parent entity.
++ */
++static bool bfq_update_parent_budget(struct bfq_entity *next_in_service)
+ {
+ struct bfq_entity *bfqg_entity;
+ struct bfq_group *bfqg;
+ struct bfq_sched_data *group_sd;
++ bool ret = false;
+
+ BUG_ON(!next_in_service);
+
+@@ -41,60 +179,68 @@ static void bfq_update_budget(struct bfq_entity *next_in_service)
+ * as it must never become an in-service entity.
+ */
+ bfqg_entity = bfqg->my_entity;
+- if (bfqg_entity)
++ if (bfqg_entity) {
++ if (bfqg_entity->budget > next_in_service->budget)
++ ret = true;
+ bfqg_entity->budget = next_in_service->budget;
++ }
++
++ return ret;
+ }
+
+-static int bfq_update_next_in_service(struct bfq_sched_data *sd)
++/*
++ * This function tells whether entity stops being a candidate for next
++ * service, according to the following logic.
++ *
++ * This function is invoked for an entity that is about to be set in
++ * service. If such an entity is a queue, then the entity is no longer
++ * a candidate for next service (i.e, a candidate entity to serve
++ * after the in-service entity is expired). The function then returns
++ * true.
++ *
++ * In contrast, the entity could stil be a candidate for next service
++ * if it is not a queue, and has more than one child. In fact, even if
++ * one of its children is about to be set in service, other children
++ * may still be the next to serve. As a consequence, a non-queue
++ * entity is not a candidate for next-service only if it has only one
++ * child. And only if this condition holds, then the function returns
++ * true for a non-queue entity.
++ */
++static bool bfq_no_longer_next_in_service(struct bfq_entity *entity)
+ {
+- struct bfq_entity *next_in_service;
++ struct bfq_group *bfqg;
+
+- if (sd->in_service_entity)
+- /* will update/requeue at the end of service */
+- return 0;
++ if (bfq_entity_to_bfqq(entity))
++ return true;
+
+- /*
+- * NOTE: this can be improved in many ways, such as returning
+- * 1 (and thus propagating upwards the update) only when the
+- * budget changes, or caching the bfqq that will be scheduled
+- * next from this subtree. By now we worry more about
+- * correctness than about performance...
+- */
+- next_in_service = bfq_lookup_next_entity(sd, 0, NULL);
+- sd->next_in_service = next_in_service;
++ bfqg = container_of(entity, struct bfq_group, entity);
+
+- if (next_in_service)
+- bfq_update_budget(next_in_service);
++ BUG_ON(bfqg == ((struct bfq_data *)(bfqg->bfqd))->root_group);
++ BUG_ON(bfqg->active_entities == 0);
++ if (bfqg->active_entities == 1)
++ return true;
+
+- return 1;
++ return false;
}
-static void bfq_check_next_in_service(struct bfq_sched_data *sd,
- struct bfq_entity *entity)
-{
+- BUG_ON(sd->next_in_service != entity);
-}
--
--static void bfq_update_budget(struct bfq_entity *next_in_service)
-+static void bfq_update_parent_budget(struct bfq_entity *next_in_service)
+-#else
++#else /* CONFIG_BFQ_GROUP_IOSCHED */
+ #define for_each_entity(entity) \
+ for (; entity ; entity = NULL)
+
+ #define for_each_entity_safe(entity, parent) \
+ for (parent = NULL; entity ; entity = parent)
+
+-static int bfq_update_next_in_service(struct bfq_sched_data *sd)
++static bool bfq_update_parent_budget(struct bfq_entity *next_in_service)
{
+- return 0;
++ return false;
}
- #endif
-@@ -105,18 +213,6 @@ static void bfq_update_budget(struct bfq_entity *next_in_service)
+
+-static void bfq_check_next_in_service(struct bfq_sched_data *sd,
+- struct bfq_entity *entity)
++static bool bfq_no_longer_next_in_service(struct bfq_entity *entity)
+ {
++ return true;
+ }
+
+-static void bfq_update_budget(struct bfq_entity *next_in_service)
+-{
+-}
+-#endif
++#endif /* CONFIG_BFQ_GROUP_IOSCHED */
+
+ /*
+ * Shift for timestamp calculations. This actually limits the maximum
+@@ -105,18 +251,6 @@ static void bfq_update_budget(struct bfq_entity *next_in_service)
*/
#define WFQ_SERVICE_SHIFT 22
@@ -6511,7 +6569,7 @@ index a5ed694..4af77f4 100644
static struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity)
{
struct bfq_queue *bfqq = NULL;
-@@ -151,20 +247,36 @@ static u64 bfq_delta(unsigned long service, unsigned long weight)
+@@ -151,20 +285,36 @@ static u64 bfq_delta(unsigned long service, unsigned long weight)
static void bfq_calc_finish(struct bfq_entity *entity, unsigned long service)
{
struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
@@ -6550,7 +6608,7 @@ index a5ed694..4af77f4 100644
}
}
-@@ -293,10 +405,26 @@ static void bfq_update_min(struct bfq_entity *entity, struct rb_node *node)
+@@ -293,10 +443,26 @@ static void bfq_update_min(struct bfq_entity *entity, struct rb_node *node)
static void bfq_update_active_node(struct rb_node *node)
{
struct bfq_entity *entity = rb_entry(node, struct bfq_entity, rb_node);
@@ -6577,7 +6635,7 @@ index a5ed694..4af77f4 100644
}
/**
-@@ -386,8 +514,6 @@ static void bfq_active_insert(struct bfq_service_tree *st,
+@@ -386,8 +552,6 @@ static void bfq_active_insert(struct bfq_service_tree *st,
BUG_ON(!bfqg);
BUG_ON(!bfqd);
bfqg->active_entities++;
@@ -6586,7 +6644,7 @@ index a5ed694..4af77f4 100644
}
#endif
}
-@@ -399,7 +525,7 @@ static void bfq_active_insert(struct bfq_service_tree *st,
+@@ -399,7 +563,7 @@ static void bfq_active_insert(struct bfq_service_tree *st,
static unsigned short bfq_ioprio_to_weight(int ioprio)
{
BUG_ON(ioprio < 0 || ioprio >= IOPRIO_BE_NR);
@@ -6595,7 +6653,7 @@ index a5ed694..4af77f4 100644
}
/**
-@@ -422,9 +548,9 @@ static void bfq_get_entity(struct bfq_entity *entity)
+@@ -422,9 +586,9 @@ static void bfq_get_entity(struct bfq_entity *entity)
struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
if (bfqq) {
@@ -6607,7 +6665,7 @@ index a5ed694..4af77f4 100644
}
}
-@@ -499,10 +625,6 @@ static void bfq_active_extract(struct bfq_service_tree *st,
+@@ -499,10 +663,6 @@ static void bfq_active_extract(struct bfq_service_tree *st,
BUG_ON(!bfqd);
BUG_ON(!bfqg->active_entities);
bfqg->active_entities--;
@@ -6618,7 +6676,7 @@ index a5ed694..4af77f4 100644
}
#endif
}
-@@ -547,12 +669,12 @@ static void bfq_forget_entity(struct bfq_service_tree *st,
+@@ -547,12 +707,12 @@ static void bfq_forget_entity(struct bfq_service_tree *st,
BUG_ON(!entity->on_st);
@@ -6633,7 +6691,7 @@ index a5ed694..4af77f4 100644
bfq_put_queue(bfqq);
}
}
-@@ -602,7 +724,7 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
+@@ -602,7 +762,7 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
if (entity->prio_changed) {
struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
@@ -6642,7 +6700,7 @@ index a5ed694..4af77f4 100644
struct bfq_data *bfqd = NULL;
struct rb_root *root;
#ifdef CONFIG_BFQ_GROUP_IOSCHED
-@@ -630,7 +752,10 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
+@@ -630,7 +790,10 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
entity->new_weight > BFQ_MAX_WEIGHT) {
pr_crit("update_weight_prio: new_weight %d\n",
entity->new_weight);
@@ -6654,7 +6712,7 @@ index a5ed694..4af77f4 100644
}
entity->orig_weight = entity->new_weight;
if (bfqq)
-@@ -661,6 +786,13 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
+@@ -661,6 +824,13 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
* associated with its new weight.
*/
if (prev_weight != new_weight) {
@@ -6668,7 +6726,7 @@ index a5ed694..4af77f4 100644
root = bfqq ? &bfqd->queue_weights_tree :
&bfqd->group_weights_tree;
bfq_weights_tree_remove(bfqd, entity, root);
-@@ -707,7 +839,7 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
+@@ -707,7 +877,7 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
st = bfq_entity_service_tree(entity);
entity->service += served;
@@ -6677,7 +6735,7 @@ index a5ed694..4af77f4 100644
BUG_ON(st->wsum == 0);
st->vtime += bfq_delta(served, st->wsum);
-@@ -716,170 +848,419 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
+@@ -716,170 +886,419 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
#ifdef CONFIG_BFQ_GROUP_IOSCHED
bfqg_stats_set_start_empty_time(bfqq_group(bfqq));
#endif
@@ -6731,17 +6789,17 @@ index a5ed694..4af77f4 100644
+ if (time_ms > 0 && time_ms < timeout_ms)
+ tot_serv_to_charge =
+ (bfqd->bfq_max_budget * time_ms) / timeout_ms;
-+
+
+- bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget");
+ if (tot_serv_to_charge < entity->service)
+ tot_serv_to_charge = entity->service;
-- bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget");
+- bfq_bfqq_served(bfqq, entity->budget - entity->service);
+ bfq_log_bfqq(bfqq->bfqd, bfqq,
+ "charge_time: %lu/%u ms, %d/%d/%d sectors",
+ time_ms, timeout_ms, entity->service,
+ tot_serv_to_charge, entity->budget);
-
-- bfq_bfqq_served(bfqq, entity->budget - entity->service);
++
+ /* Increase budget to avoid inconsistencies */
+ if (tot_serv_to_charge > entity->budget)
+ entity->budget = tot_serv_to_charge;
@@ -6948,19 +7006,20 @@ index a5ed694..4af77f4 100644
- * @entity: the entity to activate.
+ * __bfq_requeue_entity - handle requeueing or repositioning of an entity.
+ * @entity: the entity being requeued or repositioned.
- *
-- * Activate @entity and all the entities on the path from it to the root.
++ *
+ * Requeueing is needed if this entity stops being served, which
+ * happens if a leaf descendant entity has expired. On the other hand,
+ * repositioning is needed if the next_inservice_entity for the child
+ * entity has changed. See the comments inside the function for
+ * details.
-+ *
+ *
+- * Activate @entity and all the entities on the path from it to the root.
+ * Basically, this function: 1) removes entity from its active tree if
+ * present there, 2) updates the timestamps of entity and 3) inserts
+ * entity back into its active tree (in the new, right position for
+ * the new values of the timestamps).
-+ */
+ */
+-static void bfq_activate_entity(struct bfq_entity *entity)
+static void __bfq_requeue_entity(struct bfq_entity *entity)
+{
+ struct bfq_sched_data *sd = entity->sched_data;
@@ -7065,8 +7124,7 @@ index a5ed694..4af77f4 100644
+ * @requeue: true if this is a requeue, which implies that bfqq is
+ * being expired; thus ALL its ancestors stop being served and must
+ * therefore be requeued
- */
--static void bfq_activate_entity(struct bfq_entity *entity)
++ */
+static void bfq_activate_requeue_entity(struct bfq_entity *entity,
+ bool non_blocking_wait_rq,
+ bool requeue)
@@ -7186,7 +7244,7 @@ index a5ed694..4af77f4 100644
{
struct bfq_sched_data *sd;
struct bfq_entity *parent;
-@@ -887,63 +1268,153 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
+@@ -887,63 +1306,154 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
for_each_entity_safe(entity, parent) {
sd = entity->sched_data;
@@ -7309,7 +7367,8 @@ index a5ed694..4af77f4 100644
+ if (!bfq_update_next_in_service(sd, entity) &&
+ !expiration)
+ /*
-+ * next_in_service unchanged, and no
++ * next_in_service unchanged or not causing
++ * any change in entity->parent->sd, and no
+ * requeueing needed for expiration: stop
+ * here.
+ */
@@ -7339,13 +7398,13 @@ index a5ed694..4af77f4 100644
- struct bfq_entity *entry;
- struct rb_node *node = st->active.rb_node;
+ struct bfq_entity *root_entity = bfq_root_active_entity(&st->active);
++
++ if (bfq_gt(root_entity->min_start, st->vtime)) {
++ struct bfq_queue *bfqq = bfq_entity_to_bfqq(root_entity);
- entry = rb_entry(node, struct bfq_entity, rb_node);
- if (bfq_gt(entry->min_start, st->vtime)) {
- st->vtime = entry->min_start;
-+ if (bfq_gt(root_entity->min_start, st->vtime)) {
-+ struct bfq_queue *bfqq = bfq_entity_to_bfqq(root_entity);
-+
+ if (bfqq)
+ bfq_log_bfqq(bfqq->bfqd, bfqq,
+ "calc_vtime_jump: new value %llu",
@@ -7373,7 +7432,7 @@ index a5ed694..4af77f4 100644
bfq_forget_idle(st);
}
}
-@@ -952,6 +1423,7 @@ static void bfq_update_vtime(struct bfq_service_tree *st)
+@@ -952,6 +1462,7 @@ static void bfq_update_vtime(struct bfq_service_tree *st)
* bfq_first_active_entity - find the eligible entity with
* the smallest finish time
* @st: the service tree to select from.
@@ -7381,7 +7440,7 @@ index a5ed694..4af77f4 100644
*
* This function searches the first schedulable entity, starting from the
* root of the tree and going on the left every time on this side there is
-@@ -959,7 +1431,8 @@ static void bfq_update_vtime(struct bfq_service_tree *st)
+@@ -959,7 +1470,8 @@ static void bfq_update_vtime(struct bfq_service_tree *st)
* the right is followed only if a) the left subtree contains no eligible
* entities and b) no eligible entity has been found yet.
*/
@@ -7391,7 +7450,7 @@ index a5ed694..4af77f4 100644
{
struct bfq_entity *entry, *first = NULL;
struct rb_node *node = st->active.rb_node;
-@@ -967,15 +1440,15 @@ static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
+@@ -967,15 +1479,15 @@ static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
while (node) {
entry = rb_entry(node, struct bfq_entity, rb_node);
left:
@@ -7410,7 +7469,7 @@ index a5ed694..4af77f4 100644
node = node->rb_left;
goto left;
}
-@@ -993,31 +1466,84 @@ static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
+@@ -993,31 +1505,84 @@ static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
* __bfq_lookup_next_entity - return the first eligible entity in @st.
* @st: the service tree.
*
@@ -7510,7 +7569,7 @@ index a5ed694..4af77f4 100644
return entity;
}
-@@ -1025,50 +1551,118 @@ static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st,
+@@ -1025,50 +1590,81 @@ static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st,
/**
* bfq_lookup_next_entity - return the first eligible entity in @sd.
* @sd: the sched_data.
@@ -7620,48 +7679,11 @@ index a5ed694..4af77f4 100644
+
+ return sd->next_in_service != sd->in_service_entity;
+}
-+
-+/*
-+ * This function tells whether entity stops being a candidate for next
-+ * service, according to the following logic.
-+ *
-+ * This function is invoked for an entity that is about to be set in
-+ * service. If such an entity is a queue, then the entity is no longer
-+ * a candidate for next service (i.e, a candidate entity to serve
-+ * after the in-service entity is expired). The function then returns
-+ * true.
-+ *
-+ * In contrast, the entity could stil be a candidate for next service
-+ * if it is not a queue, and has more than one child. In fact, even if
-+ * one of its children is about to be set in service, other children
-+ * may still be the next to serve. As a consequence, a non-queue
-+ * entity is not a candidate for next-service only if it has only one
-+ * child. And only if this condition holds, then the function returns
-+ * true for a non-queue entity.
-+ */
-+static bool bfq_no_longer_next_in_service(struct bfq_entity *entity)
-+{
-+ struct bfq_group *bfqg;
-+
-+ if (bfq_entity_to_bfqq(entity))
-+ return true;
-+
-+#ifdef CONFIG_BFQ_GROUP_IOSCHED
-+ bfqg = container_of(entity, struct bfq_group, entity);
-+
-+ BUG_ON(bfqg == ((struct bfq_data *)(bfqg->bfqd))->root_group);
-+ BUG_ON(bfqg->active_entities == 0);
-+ if (bfqg->active_entities == 1)
-+ return true;
-+#endif
-+
-+ return false;
-+}
+
/*
* Get next queue for service.
*/
-@@ -1083,58 +1677,208 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
+@@ -1083,58 +1679,208 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
if (bfqd->busy_queues == 0)
return NULL;
@@ -7883,7 +7905,7 @@ index a5ed694..4af77f4 100644
{
BUG_ON(!bfq_bfqq_busy(bfqq));
BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list));
-@@ -1146,27 +1890,20 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+@@ -1146,27 +1892,20 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
BUG_ON(bfqd->busy_queues == 0);
bfqd->busy_queues--;
@@ -7918,7 +7940,7 @@ index a5ed694..4af77f4 100644
}
/*
-@@ -1184,16 +1921,11 @@ static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+@@ -1184,16 +1923,11 @@ static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq)
bfq_mark_bfqq_busy(bfqq);
bfqd->busy_queues++;
@@ -7938,13 +7960,13 @@ index a5ed694..4af77f4 100644
bfqd->wr_busy_queues++;
}
diff --git a/block/bfq.h b/block/bfq.h
-index fcce855..57ab51d 100644
+index fcce855..bef8244 100644
--- a/block/bfq.h
+++ b/block/bfq.h
@@ -1,5 +1,5 @@
/*
- * BFQ-v7r11 for 4.5.0: data structures and common functions prototypes.
-+ * BFQ v8r6 for 4.9.0: data structures and common functions prototypes.
++ * BFQ v8r7 for 4.9.0: data structures and common functions prototypes.
*
* Based on ideas and code from CFQ:
* Copyright (C) 2003 Jens Axboe
diff --git a/kernel/tools/cpupowertools/files/patches/mageia/block-update-bfq-from-v8r7-to-v8r10.patch b/kernel/tools/cpupowertools/files/patches/mageia/block-update-bfq-from-v8r7-to-v8r10.patch
new file mode 100644
index 00000000..17cea46c
--- /dev/null
+++ b/kernel/tools/cpupowertools/files/patches/mageia/block-update-bfq-from-v8r7-to-v8r10.patch
@@ -0,0 +1,729 @@
+ 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
+ *
+- * Copyright (C) 2016 Paolo Valente
++ * Copyright (C) 2017 Paolo Valente
+ *
+ * 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<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
+@@ -9,7 +9,7 @@
+ *
+ * Copyright (C) 2015 Paolo Valente
+ *
+- * Copyright (C) 2016 Paolo Valente
++ * Copyright (C) 2017 Paolo Valente
+ */
+
+ #ifndef _BFQ_H
diff --git a/kernel/tools/cpupowertools/files/patches/mageia/fs-jbd2-Fix-dbench4-performance-regression-for-nobarrier-mounts.patch b/kernel/tools/cpupowertools/files/patches/mageia/fs-jbd2-Fix-dbench4-performance-regression-for-nobarrier-mounts.patch
new file mode 100644
index 00000000..6c29cbbf
--- /dev/null
+++ b/kernel/tools/cpupowertools/files/patches/mageia/fs-jbd2-Fix-dbench4-performance-regression-for-nobarrier-mounts.patch
@@ -0,0 +1,39 @@
+From: Jan Kara
+Subject: [PATCH] jbd2: Fix dbench4 performance regression for 'nobarrier' mounts
+Date: Fri, 28 Apr 2017 11:59:34 +0200
+
+Commit b685d3d65ac7 "block: treat REQ_FUA and REQ_PREFLUSH as
+synchronous" removed REQ_SYNC flag from WRITE_FUA implementation. Since
+JBD2 strips REQ_FUA and REQ_FLUSH flags from submitted IO when the
+filesystem is mounted with nobarrier mount option, journal superblock
+writes ended up being async writes after this patch and that caused
+heavy performance regression for dbench4 benchmark with high number of
+processes. In my test setup with HP RAID array with non-volatile write
+cache and 32 GB ram, dbench4 runs with 8 processes regressed by ~25%.
+
+Fix the problem by making sure journal superblock writes are always
+treated as synchronous since they generally block progress of the
+journalling machinery and thus the whole filesystem.
+
+Fixes: b685d3d65ac791406e0dfd8779cc9b3707fea5a3
+CC: stable@vger.kernel.org
+Signed-off-by: Jan Kara
+---
+ fs/jbd2/journal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
+index 5adc2fb62b0f..e768126f6a72 100644
+--- a/fs/jbd2/journal.c
++++ b/fs/jbd2/journal.c
+@@ -1348,7 +1348,7 @@ static int jbd2_write_superblock(journal_t *journal, int write_flags)
+ jbd2_superblock_csum_set(journal, sb);
+ get_bh(bh);
+ bh->b_end_io = end_buffer_write_sync;
+- ret = submit_bh(REQ_OP_WRITE, write_flags, bh);
++ ret = submit_bh(REQ_OP_WRITE, write_flags | REQ_SYNC, bh);
+ wait_on_buffer(bh);
+ if (buffer_write_io_error(bh)) {
+ clear_buffer_write_io_error(bh);
+--
+2.12.0
diff --git a/kernel/tools/cpupowertools/files/patches/mageia/gpu-drm-amd-amdgpu-add-POLARIS12-PCI-ID.patch b/kernel/tools/cpupowertools/files/patches/mageia/gpu-drm-amd-amdgpu-add-POLARIS12-PCI-ID.patch
new file mode 100644
index 00000000..e8bff963
--- /dev/null
+++ b/kernel/tools/cpupowertools/files/patches/mageia/gpu-drm-amd-amdgpu-add-POLARIS12-PCI-ID.patch
@@ -0,0 +1,28 @@
+From cf8c73afb3abf0f8905efbaddd4ce11a0deec9da Mon Sep 17 00:00:00 2001
+From: Evan Quan
+Date: Fri, 17 Mar 2017 10:22:51 +0800
+Subject: [PATCH] drm/amd/amdgpu: add POLARIS12 PCI ID
+
+Signed-off-by: Evan Quan
+Reviewed-by: Junwei Zhang
+Signed-off-by: Alex Deucher
+Cc: stable@vger.kernel.org
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+index f7adbac..b76cd69 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -421,6 +421,7 @@ static const struct pci_device_id pciidlist[] = {
+ {0x1002, 0x6985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
+ {0x1002, 0x6986, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
+ {0x1002, 0x6987, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
++ {0x1002, 0x6995, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
+ {0x1002, 0x699F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_POLARIS12},
+
+ {0, 0, 0}
+--
+2.10.2
+
diff --git a/kernel/tools/cpupowertools/files/patches/mageia/net-macsec-dynamically-allocate-space-for-sglist.patch b/kernel/tools/cpupowertools/files/patches/mageia/net-macsec-dynamically-allocate-space-for-sglist.patch
new file mode 100644
index 00000000..abbb40d6
--- /dev/null
+++ b/kernel/tools/cpupowertools/files/patches/mageia/net-macsec-dynamically-allocate-space-for-sglist.patch
@@ -0,0 +1,117 @@
+From 5294b83086cc1c35b4efeca03644cf9d12282e5b Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld"
+Date: Tue, 25 Apr 2017 19:08:18 +0200
+Subject: [PATCH] macsec: dynamically allocate space for sglist
+
+We call skb_cow_data, which is good anyway to ensure we can actually
+modify the skb as such (another error from prior). Now that we have the
+number of fragments required, we can safely allocate exactly that amount
+of memory.
+
+Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver")
+Signed-off-by: Jason A. Donenfeld
+Acked-by: Sabrina Dubroca
+Signed-off-by: David S. Miller
+---
+ drivers/net/macsec.c | 29 ++++++++++++++++++++++-------
+ 1 file changed, 22 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index dbab05a..49ce4e9 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -617,7 +617,8 @@ static void macsec_encrypt_done(struct crypto_async_request *base, int err)
+
+ static struct aead_request *macsec_alloc_req(struct crypto_aead *tfm,
+ unsigned char **iv,
+- struct scatterlist **sg)
++ struct scatterlist **sg,
++ int num_frags)
+ {
+ size_t size, iv_offset, sg_offset;
+ struct aead_request *req;
+@@ -629,7 +630,7 @@ static struct aead_request *macsec_alloc_req(struct crypto_aead *tfm,
+
+ size = ALIGN(size, __alignof__(struct scatterlist));
+ sg_offset = size;
+- size += sizeof(struct scatterlist) * (MAX_SKB_FRAGS + 1);
++ size += sizeof(struct scatterlist) * num_frags;
+
+ tmp = kmalloc(size, GFP_ATOMIC);
+ if (!tmp)
+@@ -649,6 +650,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
+ {
+ int ret;
+ struct scatterlist *sg;
++ struct sk_buff *trailer;
+ unsigned char *iv;
+ struct ethhdr *eth;
+ struct macsec_eth_header *hh;
+@@ -723,7 +725,14 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
+ return ERR_PTR(-EINVAL);
+ }
+
+- req = macsec_alloc_req(tx_sa->key.tfm, &iv, &sg);
++ ret = skb_cow_data(skb, 0, &trailer);
++ if (unlikely(ret < 0)) {
++ macsec_txsa_put(tx_sa);
++ kfree_skb(skb);
++ return ERR_PTR(ret);
++ }
++
++ req = macsec_alloc_req(tx_sa->key.tfm, &iv, &sg, ret);
+ if (!req) {
+ macsec_txsa_put(tx_sa);
+ kfree_skb(skb);
+@@ -732,7 +741,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
+
+ macsec_fill_iv(iv, secy->sci, pn);
+
+- sg_init_table(sg, MAX_SKB_FRAGS + 1);
++ sg_init_table(sg, ret);
+ skb_to_sgvec(skb, sg, 0, skb->len);
+
+ if (tx_sc->encrypt) {
+@@ -917,6 +926,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
+ {
+ int ret;
+ struct scatterlist *sg;
++ struct sk_buff *trailer;
+ unsigned char *iv;
+ struct aead_request *req;
+ struct macsec_eth_header *hdr;
+@@ -927,7 +937,12 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
+ if (!skb)
+ return ERR_PTR(-ENOMEM);
+
+- req = macsec_alloc_req(rx_sa->key.tfm, &iv, &sg);
++ ret = skb_cow_data(skb, 0, &trailer);
++ if (unlikely(ret < 0)) {
++ kfree_skb(skb);
++ return ERR_PTR(ret);
++ }
++ req = macsec_alloc_req(rx_sa->key.tfm, &iv, &sg, ret);
+ if (!req) {
+ kfree_skb(skb);
+ return ERR_PTR(-ENOMEM);
+@@ -936,7 +951,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
+ hdr = (struct macsec_eth_header *)skb->data;
+ macsec_fill_iv(iv, sci, ntohl(hdr->packet_number));
+
+- sg_init_table(sg, MAX_SKB_FRAGS + 1);
++ sg_init_table(sg, ret);
+ skb_to_sgvec(skb, sg, 0, skb->len);
+
+ if (hdr->tci_an & MACSEC_TCI_E) {
+@@ -2716,7 +2731,7 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
+ }
+
+ #define MACSEC_FEATURES \
+- (NETIF_F_SG | NETIF_F_HIGHDMA)
++ (NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST)
+ static struct lock_class_key macsec_netdev_addr_lock_key;
+
+ static int macsec_dev_init(struct net_device *dev)
+--
+2.10.2
+
diff --git a/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-iwlwifi-fix-MODULE_FIRMWARE-for-6030.patch b/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-iwlwifi-fix-MODULE_FIRMWARE-for-6030.patch
new file mode 100644
index 00000000..c996a702
--- /dev/null
+++ b/kernel/tools/cpupowertools/files/patches/mageia/net-wireless-iwlwifi-fix-MODULE_FIRMWARE-for-6030.patch
@@ -0,0 +1,32 @@
+From d8320d75b59ecdc1b8e60ac793d3a54d84333a18 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?J=C3=BCrg=20Billeter?=
+Date: Mon, 10 Oct 2016 18:30:00 +0200
+Subject: [PATCH] iwlwifi: fix MODULE_FIRMWARE for 6030
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+IWL6000G2B_UCODE_API_MAX is not defined. ucode_api_max of
+IWL_DEVICE_6030 uses IWL6000G2_UCODE_API_MAX. Use this also for
+MODULE_FIRMWARE.
+
+Fixes: 9d9b21d1b616 ("iwlwifi: remove IWL_*_UCODE_API_OK")
+Signed-off-by: Jürg Billeter
+Signed-off-by: Luca Coelho
+---
+ drivers/net/wireless/intel/iwlwifi/iwl-6000.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-6000.c b/drivers/net/wireless/intel/iwlwifi/iwl-6000.c
+index 0b9f6a7..39335b7 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-6000.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-6000.c
+@@ -371,4 +371,4 @@ const struct iwl_cfg iwl6000_3agn_cfg = {
+ MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
+ MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
+ MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
+-MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_MAX));
++MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
+--
+2.10.2
+
diff --git a/kernel/tools/cpupowertools/files/patches/mageia/series b/kernel/tools/cpupowertools/files/patches/mageia/series
index 92c06398..a5ce22a7 100644
--- a/kernel/tools/cpupowertools/files/patches/mageia/series
+++ b/kernel/tools/cpupowertools/files/patches/mageia/series
@@ -14,7 +14,6 @@
###
### Stable Queue
###
-patch-4.9.19-rc1.patch
###
### Arch x86
@@ -131,7 +130,8 @@ block-Make-CFQ-default-to-IOPS-mode-on-SSDs.patch
block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.5.0.patch
block-introduce-the-BFQ-v7r11-I-O-sched-for-4.5.0.patch
block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for.patch
-block-Turn-into-BFQ-v8r6-for-4.9.0.patch
+block-Turn-into-BFQ-v8r7-for-4.9.0.patch
+block-update-bfq-from-v8r7-to-v8r10.patch
# new macbooks
block-nvme-detect-NVMe-controller-in-recent-MacBooks.patch
@@ -160,6 +160,9 @@ fs-aufs-4.9-modular.patch
# needed for mdadm: imsm: enable bad block support for imsm metadata
fs-seq_file-reset-iterator-to-first-record-for-zero-off.patch
+# performance regression fix
+fs-jbd2-Fix-dbench4-performance-regression-for-nobarrier-mounts.patch
+
###
### FireWire
###
@@ -200,6 +203,7 @@ gpu-drm-i915-don-t-warn-about-Skylake-CPU-KabyPoint-PCH-.patch
gpu-drm-amd-amdgpu-add-Polaris12-PCI-ID.patch
gpu-drm-amd-amdgpu-add-Polaris12-support-v3.patch
gpu-drm-amdgpu-powerplay-add-Polaris12-support.patch
+gpu-drm-amd-amdgpu-add-POLARIS12-PCI-ID.patch
# fix crash
gpu-drm-amdgpu-pm-check-for-headless-before-calling-comp.patch
@@ -256,6 +260,9 @@ net-netfilter-psd-mdv.patch
net-netfilter-psd-2.6.35-buildfix.patch
net-netfilter-psd-fix-redefines.patch
+# iwlwifi fixes
+net-wireless-iwlwifi-fix-MODULE_FIRMWARE-for-6030.patch
+
# rtlwifi fixes
net-wireless-rtlwifi-Use-dev_kfree_skb_irq-instead-of-kfree_skb.patch
net-wireless-rtlwifi-Fix-kernel-oops-introduced-with-commit-e4965.patch
@@ -266,6 +273,9 @@ net-wireless-realtek-rtl8xxxu-linux-4.11-rc.patch
# WireGuard support
net-wireguard.patch
+# CVE-2017-7477
+net-macsec-dynamically-allocate-space-for-sglist.patch
+
###
### Platform drivers
###
@@ -295,6 +305,12 @@ include-kbuild-export-pci_ids.patch
sound-ALSA-hda-realtek-Add-new-codec-ID-ALC299.patch
sound-ALSA-hda-realtek-New-codec-support-of-ALC1220.patch
+# add support for Gigabyte GA-AX370 Gaming 5 with dual codecs (TTL: 4.12)
+sound-ALSA-hda-A-new-flag-to-enforce-prefix-to-each-pin.patch
+sound-ALSA-hda-Allow-to-enable-disable-vmaster-build-expli.patch
+sound-ALSA-hda-Support-Gigabyte-Gaming-board-with-dual-Rea.patch
+sound-ALSA-hda-Use-a-helper-function-for-renaming-kctl-nam.patch
+
###
### Staging
###
diff --git a/kernel/tools/cpupowertools/files/patches/mageia/sound-ALSA-hda-A-new-flag-to-enforce-prefix-to-each-pin.patch b/kernel/tools/cpupowertools/files/patches/mageia/sound-ALSA-hda-A-new-flag-to-enforce-prefix-to-each-pin.patch
new file mode 100644
index 00000000..1899b308
--- /dev/null
+++ b/kernel/tools/cpupowertools/files/patches/mageia/sound-ALSA-hda-A-new-flag-to-enforce-prefix-to-each-pin.patch
@@ -0,0 +1,68 @@
+From 9f3dadb156692e15933a4a97ef659f65151be4a1 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai
+Date: Mon, 10 Apr 2017 17:12:33 +0200
+Subject: [PATCH 1/4] ALSA: hda - A new flag to enforce prefix to each pin
+
+This is a preliminary patch for a smooth multi-codec support, and it
+introduces a new flag, force_pin_prefix, to struct hda_codec.
+This flag is used to force to add the pin location prefix to each
+input pin. For example, when there is only one microphone pin,
+usually the auto-parser assigns the string "Mic". With this flag on,
+it'll be like "Front Mic". Also, the creation of "Master" or "PCM"
+playback volume for a single pin is suppressed, too.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=195305
+Signed-off-by: Takashi Iwai
+---
+ sound/pci/hda/hda_auto_parser.c | 1 +
+ sound/pci/hda/hda_codec.h | 1 +
+ sound/pci/hda/hda_generic.c | 2 ++
+ 3 files changed, 4 insertions(+)
+
+diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
+index a03cf68..d3ea731 100644
+--- a/sound/pci/hda/hda_auto_parser.c
++++ b/sound/pci/hda/hda_auto_parser.c
+@@ -580,6 +580,7 @@ const char *hda_get_autocfg_input_label(struct hda_codec *codec,
+ has_multiple_pins = 1;
+ if (has_multiple_pins && type == AUTO_PIN_MIC)
+ has_multiple_pins &= check_mic_location_need(codec, cfg, input);
++ has_multiple_pins |= codec->force_pin_prefix;
+ return hda_get_input_pin_label(codec, &cfg->inputs[input],
+ cfg->inputs[input].pin,
+ has_multiple_pins);
+diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
+index f17f252..d6fb2d5 100644
+--- a/sound/pci/hda/hda_codec.h
++++ b/sound/pci/hda/hda_codec.h
+@@ -256,6 +256,7 @@ struct hda_codec {
+ unsigned int dump_coef:1; /* dump processing coefs in codec proc file */
+ unsigned int power_save_node:1; /* advanced PM for each widget */
+ unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */
++ unsigned int force_pin_prefix:1; /* Add location prefix */
+ #ifdef CONFIG_PM
+ unsigned long power_on_acct;
+ unsigned long power_off_acct;
+diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
+index e7c8f4f..4438328 100644
+--- a/sound/pci/hda/hda_generic.c
++++ b/sound/pci/hda/hda_generic.c
+@@ -1125,6 +1125,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
+
+ *index = 0;
+ if (cfg->line_outs == 1 && !spec->multi_ios &&
++ !codec->force_pin_prefix &&
+ !cfg->hp_outs && !cfg->speaker_outs)
+ return spec->vmaster_mute.hook ? "PCM" : "Master";
+
+@@ -1132,6 +1133,7 @@ static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
+ * use it master (or "PCM" if a vmaster hook is present)
+ */
+ if (spec->multiout.num_dacs == 1 && !spec->mixer_nid &&
++ !codec->force_pin_prefix &&
+ !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0])
+ return spec->vmaster_mute.hook ? "PCM" : "Master";
+
+--
+2.10.2
+
diff --git a/kernel/tools/cpupowertools/files/patches/mageia/sound-ALSA-hda-Allow-to-enable-disable-vmaster-build-expli.patch b/kernel/tools/cpupowertools/files/patches/mageia/sound-ALSA-hda-Allow-to-enable-disable-vmaster-build-expli.patch
new file mode 100644
index 00000000..57b07e2f
--- /dev/null
+++ b/kernel/tools/cpupowertools/files/patches/mageia/sound-ALSA-hda-Allow-to-enable-disable-vmaster-build-expli.patch
@@ -0,0 +1,78 @@
+From 7480316c265c9fcdbf73b1b8dec061b893b7e987 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai
+Date: Mon, 10 Apr 2017 17:37:34 +0200
+Subject: [PATCH 2/4] ALSA: hda - Allow to enable/disable vmaster build
+ explicitly
+
+Another preliminary patch for the dual-codec support: since the
+support of vmaster over multiple codecs is difficult, simply disable
+it by a new flag to hda_codec struct. A new user hint is added as
+well for consistency.
+
+Signed-off-by: Takashi Iwai
+---
+ Documentation/sound/hd-audio/notes.rst | 2 ++
+ sound/pci/hda/hda_generic.c | 7 +++++--
+ sound/pci/hda/hda_generic.h | 1 +
+ 3 files changed, 8 insertions(+), 2 deletions(-)
+
+#diff --git a/Documentation/sound/hd-audio/notes.rst b/Documentation/sound/hd-audio/notes.rst
+#index 9eeb9b4..f59c3cd 100644
+#--- a/Documentation/sound/hd-audio/notes.rst
+#+++ b/Documentation/sound/hd-audio/notes.rst
+#@@ -494,6 +494,8 @@ add_hp_mic (bool)
+# hp_mic_detect (bool)
+# enable/disable the hp/mic shared input for a single built-in mic
+# case; default true
+#+vmaster (bool)
+#+ enable/disable the virtual Master control; default true
+# mixer_nid (int)
+# specifies the widget NID of the analog-loopback mixer
+#
+diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
+index 4438328..2842c82 100644
+--- a/sound/pci/hda/hda_generic.c
++++ b/sound/pci/hda/hda_generic.c
+@@ -196,6 +196,9 @@ static void parse_user_hints(struct hda_codec *codec)
+ val = snd_hda_get_bool_hint(codec, "hp_mic_detect");
+ if (val >= 0)
+ spec->suppress_hp_mic_detect = !val;
++ val = snd_hda_get_bool_hint(codec, "vmaster");
++ if (val >= 0)
++ spec->suppress_vmaster = !val;
+
+ if (!snd_hda_get_int_hint(codec, "mixer_nid", &val))
+ spec->mixer_nid = val;
+@@ -5033,7 +5036,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
+ }
+
+ /* if we have no master control, let's create it */
+- if (!spec->no_analog &&
++ if (!spec->no_analog && !spec->suppress_vmaster &&
+ !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
+ err = snd_hda_add_vmaster(codec, "Master Playback Volume",
+ spec->vmaster_tlv, slave_pfxs,
+@@ -5041,7 +5044,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
+ if (err < 0)
+ return err;
+ }
+- if (!spec->no_analog &&
++ if (!spec->no_analog && !spec->suppress_vmaster &&
+ !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
+ err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
+ NULL, slave_pfxs,
+diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
+index f66fc7e..6177231 100644
+--- a/sound/pci/hda/hda_generic.h
++++ b/sound/pci/hda/hda_generic.h
+@@ -229,6 +229,7 @@ struct hda_gen_spec {
+ unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */
+ unsigned int power_down_unused:1; /* power down unused widgets */
+ unsigned int dac_min_mute:1; /* minimal = mute for DACs */
++ unsigned int suppress_vmaster:1; /* don't create vmaster kctls */
+
+ /* other internal flags */
+ unsigned int no_analog:1; /* digital I/O only */
+--
+2.10.2
+
diff --git a/kernel/tools/cpupowertools/files/patches/mageia/sound-ALSA-hda-Support-Gigabyte-Gaming-board-with-dual-Rea.patch b/kernel/tools/cpupowertools/files/patches/mageia/sound-ALSA-hda-Support-Gigabyte-Gaming-board-with-dual-Rea.patch
new file mode 100644
index 00000000..0f93df15
--- /dev/null
+++ b/kernel/tools/cpupowertools/files/patches/mageia/sound-ALSA-hda-Support-Gigabyte-Gaming-board-with-dual-Rea.patch
@@ -0,0 +1,122 @@
+From 7beb3a6e9335d13872f24566b451f8371edd238f Mon Sep 17 00:00:00 2001
+From: Takashi Iwai
+Date: Mon, 10 Apr 2017 18:05:52 +0200
+Subject: [PATCH 3/4] ALSA: hda - Support Gigabyte Gaming board with dual
+ Realtek codecs
+
+This patch adds some workarounds to make Gigabyte GA-AX370 Gaming 5
+board working without the conflicts of kctls, etc. In general, the
+dual codec configs result in the conflicts of the following stuff:
+- Master controls
+- Capture controls
+- Analog loopback controls
+In addition, the auto-mute and the auto-mic can't work well among
+multiple codecs.
+
+The current "solution" is to disable all these features, and use UCM
+for a better PulseAudio management. For a dedicated UCM profile, the
+patch overrides the card longname so that the system an get a unique
+profile path.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=195305
+Signed-off-by: Takashi Iwai
+---
+ sound/pci/hda/patch_realtek.c | 61 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 61 insertions(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 9371f1a..e81cf83 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -1800,6 +1800,7 @@ enum {
+ ALC882_FIXUP_NO_PRIMARY_HP,
+ ALC887_FIXUP_ASUS_BASS,
+ ALC887_FIXUP_BASS_CHMAP,
++ ALC1220_FIXUP_GB_DUAL_CODECS,
+ };
+
+ static void alc889_fixup_coef(struct hda_codec *codec,
+@@ -1962,6 +1963,61 @@ static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
+ static void alc_fixup_bass_chmap(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action);
+
++/* For dual-codec configuration, we need to disable some features to avoid
++ * conflicts of kctls and PCM streams
++ */
++static void alc_fixup_dual_codecs(struct hda_codec *codec,
++ const struct hda_fixup *fix, int action)
++{
++ struct alc_spec *spec = codec->spec;
++
++ if (action != HDA_FIXUP_ACT_PRE_PROBE)
++ return;
++ /* disable vmaster */
++ spec->gen.suppress_vmaster = 1;
++ /* auto-mute and auto-mic switch don't work with multiple codecs */
++ spec->gen.suppress_auto_mute = 1;
++ spec->gen.suppress_auto_mic = 1;
++ /* disable aamix as well */
++ spec->gen.mixer_nid = 0;
++ /* add location prefix to avoid conflicts */
++ codec->force_pin_prefix = 1;
++}
++
++static void rename_ctl(struct hda_codec *codec, const char *oldname,
++ const char *newname)
++{
++ struct snd_kcontrol *kctl;
++
++ kctl = snd_hda_find_mixer_ctl(codec, oldname);
++ if (kctl)
++ strcpy(kctl->id.name, newname);
++}
++
++static void alc1220_fixup_gb_dual_codecs(struct hda_codec *codec,
++ const struct hda_fixup *fix,
++ int action)
++{
++ alc_fixup_dual_codecs(codec, fix, action);
++ switch (action) {
++ case HDA_FIXUP_ACT_PRE_PROBE:
++ /* override card longname to provide a unique UCM profile */
++ strcpy(codec->card->longname, "HDAudio-Gigabyte-ALC1220DualCodecs");
++ break;
++ case HDA_FIXUP_ACT_BUILD:
++ /* rename Capture controls depending on the codec */
++ rename_ctl(codec, "Capture Volume",
++ codec->addr == 0 ?
++ "Rear-Panel Capture Volume" :
++ "Front-Panel Capture Volume");
++ rename_ctl(codec, "Capture Switch",
++ codec->addr == 0 ?
++ "Rear-Panel Capture Switch" :
++ "Front-Panel Capture Switch");
++ break;
++ }
++}
++
+ static const struct hda_fixup alc882_fixups[] = {
+ [ALC882_FIXUP_ABIT_AW9D_MAX] = {
+ .type = HDA_FIXUP_PINS,
+@@ -2198,6 +2254,10 @@ static const struct hda_fixup alc882_fixups[] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc_fixup_bass_chmap,
+ },
++ [ALC1220_FIXUP_GB_DUAL_CODECS] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = alc1220_fixup_gb_dual_codecs,
++ },
+ };
+
+ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
+@@ -2267,6 +2327,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
+ SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
+ SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
++ SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
+ SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
+ SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
+ SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
+--
+2.10.2
+
diff --git a/kernel/tools/cpupowertools/files/patches/mageia/sound-ALSA-hda-Use-a-helper-function-for-renaming-kctl-nam.patch b/kernel/tools/cpupowertools/files/patches/mageia/sound-ALSA-hda-Use-a-helper-function-for-renaming-kctl-nam.patch
new file mode 100644
index 00000000..8094a331
--- /dev/null
+++ b/kernel/tools/cpupowertools/files/patches/mageia/sound-ALSA-hda-Use-a-helper-function-for-renaming-kctl-nam.patch
@@ -0,0 +1,42 @@
+From 56798e6b3a2264b58d50b93cfd66586ede77d661 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai
+Date: Tue, 11 Apr 2017 08:10:52 +0200
+Subject: [PATCH 4/4] ALSA: hda - Use a helper function for renaming kctl names
+
+Signed-off-by: Takashi Iwai
+---
+ sound/pci/hda/patch_realtek.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index e81cf83..57eeefd 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -4724,7 +4724,6 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec,
+ { 0x1b, 0x21114000 }, /* dock speaker pin */
+ {}
+ };
+- struct snd_kcontrol *kctl;
+
+ switch (action) {
+ case HDA_FIXUP_ACT_PRE_PROBE:
+@@ -4739,12 +4738,10 @@ static void alc282_fixup_asus_tx300(struct hda_codec *codec,
+ /* this is a bit tricky; give more sane names for the main
+ * (tablet) speaker and the dock speaker, respectively
+ */
+- kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch");
+- if (kctl)
+- strcpy(kctl->id.name, "Dock Speaker Playback Switch");
+- kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch");
+- if (kctl)
+- strcpy(kctl->id.name, "Speaker Playback Switch");
++ rename_ctl(codec, "Speaker Playback Switch",
++ "Dock Speaker Playback Switch");
++ rename_ctl(codec, "Bass Speaker Playback Switch",
++ "Speaker Playback Switch");
+ break;
+ }
+ }
+--
+2.10.2
+
diff --git a/kernel/tools/cpupowertools/pspec.xml b/kernel/tools/cpupowertools/pspec.xml
index 10e2decc..bd9fac28 100644
--- a/kernel/tools/cpupowertools/pspec.xml
+++ b/kernel/tools/cpupowertools/pspec.xml
@@ -18,8 +18,8 @@
- patches/linux/patch-4.9.18.xz
-
+ patches/linux/patch-4.9.27.xz
+
@@ -27,7 +27,7 @@
patches/mageia/base-cacheinfo-silence-DT-warnings.patch
patches/mageia/pci-add-ALI-M5229-ide-compatibility-mode-quirk.patch
patches/mageia/pci-quirks-drop-devinit-exit.patch
- patches/mageia/pci-Blacklist-AMD-Stoney-GPU-devices-for-ATS.patch
+ patches/mageia/pci-Blacklist-AMD-Stoney-GPU-devices-for-ATS.patch
patches/mageia/acpi-CLEVO-M360S-disable_acpi_irq.patch
patches/mageia/acpi-processor-M720SR-limit-to-C2.patch
patches/mageia/ACPI-video-Add-a-quirk-to-force-acpi-video-backlight.patch
@@ -49,15 +49,18 @@
+ patches/mageia/block-Turn-into-BFQ-v8r7-for-4.9.0.patch
+ patches/mageia/block-update-bfq-from-v8r7-to-v8r10.patch<2-->
patches/mageia/block-nvme-detect-NVMe-controller-in-recent-MacBooks.patch
patches/mageia/char-tpm-tpm_crb-implement-tpm-crb-idle-state.patch
patches/mageia/char-tmp-tpm_crb-fix-Intel-PTT-hw-bug-during-idle-state.patch
patches/mageia/char-tpm-tpm_crb-open-code-the-crb_init-into-acpi_add.patch
patches/mageia/char-tmp-tpm_crb-implement-runtime-pm-for-tpm_crb.patch
patches/mageia/fs-aufs-4.9.patch
+ patches/fs-aufs-4.9-posix_acl.patch
patches/mageia/fs-aufs-4.9-modular.patch
patches/mageia/fs-seq_file-reset-iterator-to-first-record-for-zero-off.patch
+ patches/mageia/fs-jbd2-Fix-dbench4-performance-regression-for-nobarrier-mounts.patch
patches/mageia/firewire-ieee1394-module-aliases.patch
patches/mageia/char-agp-intel-new-Q57-id.patch
@@ -82,6 +85,7 @@
patches/mageia/gpu-drm-amd-amdgpu-add-Polaris12-PCI-ID.patch
patches/mageia/gpu-drm-amd-amdgpu-add-Polaris12-support-v3.patch
patches/mageia/gpu-drm-amdgpu-powerplay-add-Polaris12-support.patch
+ patches/mageia/gpu-drm-amd-amdgpu-add-POLARIS12-PCI-ID.patch
patches/mageia/gpu-drm-amdgpu-pm-check-for-headless-before-calling-comp.patch
patches/mageia/input-i8042-quirks-for-Fujitsu-Lifebook-A544-and-Lif.patch
patches/mageia/net-sis190-fix-list-usage.patch
@@ -96,16 +100,22 @@
patches/mageia/net-netfilter-psd-mdv.patch
patches/mageia/net-netfilter-psd-2.6.35-buildfix.patch
patches/mageia/net-netfilter-psd-fix-redefines.patch
+ patches/mageia/net-wireless-iwlwifi-fix-MODULE_FIRMWARE-for-6030.patch
patches/mageia/net-wireless-rtlwifi-Use-dev_kfree_skb_irq-instead-of-kfree_skb.patch
patches/mageia/net-wireless-rtlwifi-Fix-kernel-oops-introduced-with-commit-e4965.patch
patches/mageia/net-wireless-realtek-rtl8xxxu-linux-4.11-rc.patch
patches/mageia/net-wireguard.patch
+ patches/mageia/net-macsec-dynamically-allocate-space-for-sglist.patch
patches/mageia/platform-x86-add-shuttle-wmi-driver.patch
patches/mageia/platform-x86-shuttle-wmi-drop-devinit-exit.patch
patches/mageia/platform-x86-shuttle-wmi-4.2-buildfix.patch
patches/mageia/include-kbuild-export-pci_ids.patch
patches/mageia/sound-ALSA-hda-realtek-Add-new-codec-ID-ALC299.patch
patches/mageia/sound-ALSA-hda-realtek-New-codec-support-of-ALC1220.patch
+ patches/mageia/sound-ALSA-hda-A-new-flag-to-enforce-prefix-to-each-pin.patch
+ patches/mageia/sound-ALSA-hda-Allow-to-enable-disable-vmaster-build-expli.patch
+ patches/mageia/sound-ALSA-hda-Support-Gigabyte-Gaming-board-with-dual-Rea.patch
+ patches/mageia/sound-ALSA-hda-Use-a-helper-function-for-renaming-kctl-nam.patch
patches/mageia/hid-usbhid-IBM-BladeCenterHS20-quirk.patch
patches/mageia/usb-storage-unusual_devs-add-id.patch
patches/mageia/usb-storage-unusual_devs-add-id-2.6.37-buildfix.patch
@@ -165,6 +175,13 @@
-->
+
+ 2017-05-10
+ 4.9.27
+ Release bump
+ PisiLinux Community
+ admin@pisilinux.org
+
2017-03-30
4.9.18