Hi Dear,
My name is Dr Lisa Williams from the United States.I am a French and
American nationality (dual) living in the U.S and sometimes in France
for Work Purpose.
I hope you consider my friend request. I will share some of my pics
and more details about myself when I get your response.
Thanks
With love
Lisa
The i801 controller provides a locking mechanism that the OS is supposed
to use to safely share the SMBus with ACPI AML or other firmware.
Previously, Linux attempted to get out of the way of ACPI AML entirely,
but left the bus locked if it used it before the first AML access. This
causes AML implementations that *do* attempt to safely share the bus
to time out if Linux uses it first; notably, this regressed ACPI video
backlight controls on 2015 iMacs after 01590f361e started instantiating
SPD EEPROMs on boot.
Commit 065b6211a8 fixed the immediate problem of leaving the bus locked,
but we can do better. The controller does have a proper locking mechanism,
so let's use it as intended. Since we can't rely on the BIOS doing this
properly, we implement the following logic:
- If ACPI AML uses the bus at all, we make a note and disable power
management. The latter matches already existing behavior.
- When we want to use the bus, we attempt to lock it first. If the
locking attempt times out, *and* ACPI hasn't tried to use the bus at
all yet, we cautiously go ahead and assume the BIOS forgot to unlock
the bus after boot. This preserves existing behavior.
- We always unlock the bus after a transfer.
- If ACPI AML tries to use the bus (except trying to lock it) while
we're in the middle of a transfer, or after we've determined
locking is broken, we know we cannot safely share the bus and give up.
Upon first usage of SMBus by ACPI AML, if nothing has gone horribly
wrong so far, users will see:
i801_smbus 0000:00:1f.4: SMBus controller is shared with ACPI AML. This seems safe so far.
If locking the SMBus times out, users will see:
i801_smbus 0000:00:1f.4: BIOS left SMBus locked
And if ACPI AML tries to use the bus concurrently with Linux, or it
previously used the bus and we failed to subsequently lock it as
above, the driver will give up and users will get:
i801_smbus 0000:00:1f.4: BIOS uses SMBus unsafely
i801_smbus 0000:00:1f.4: Driver SMBus register access inhibited
This fixes the regression introduced by 01590f361e, and further allows
safely sharing the SMBus on 2015 iMacs. Tested by running `i2cdump` in a
loop while changing backlight levels via the ACPI video device.
Fixes: 01590f361e ("i2c: i801: Instantiate SPD EEPROMs automatically")
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Hector Martin <marcan(a)marcan.st>
---
drivers/i2c/busses/i2c-i801.c | 96 ++++++++++++++++++++++++++++-------
1 file changed, 79 insertions(+), 17 deletions(-)
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 04a1e38f2a6f..03be6310d6d7 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -287,11 +287,18 @@ struct i801_priv {
#endif
struct platform_device *tco_pdev;
+ /* BIOS left the controller marked busy. */
+ bool inuse_stuck;
/*
- * If set to true the host controller registers are reserved for
- * ACPI AML use. Protected by acpi_lock.
+ * If set to true, ACPI AML uses the host controller registers.
+ * Protected by acpi_lock.
*/
- bool acpi_reserved;
+ bool acpi_usage;
+ /*
+ * If set to true, ACPI AML uses the host controller registers in an
+ * unsafe way. Protected by acpi_lock.
+ */
+ bool acpi_unsafe;
struct mutex acpi_lock;
};
@@ -854,10 +861,37 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
int hwpec;
int block = 0;
int ret = 0, xact = 0;
+ int timeout = 0;
struct i801_priv *priv = i2c_get_adapdata(adap);
+ /*
+ * The controller provides a bit that implements a mutex mechanism
+ * between users of the bus. First, try to lock the hardware mutex.
+ * If this doesn't work, we give up trying to do this, but then
+ * bail if ACPI uses SMBus at all.
+ */
+ if (!priv->inuse_stuck) {
+ while (inb_p(SMBHSTSTS(priv)) & SMBHSTSTS_INUSE_STS) {
+ if (++timeout >= MAX_RETRIES) {
+ dev_warn(&priv->pci_dev->dev,
+ "BIOS left SMBus locked\n");
+ priv->inuse_stuck = true;
+ break;
+ }
+ usleep_range(250, 500);
+ }
+ }
+
mutex_lock(&priv->acpi_lock);
- if (priv->acpi_reserved) {
+ if (priv->acpi_usage && priv->inuse_stuck && !priv->acpi_unsafe) {
+ priv->acpi_unsafe = true;
+
+ dev_warn(&priv->pci_dev->dev, "BIOS uses SMBus unsafely\n");
+ dev_warn(&priv->pci_dev->dev,
+ "Driver SMBus register access inhibited\n");
+ }
+
+ if (priv->acpi_unsafe) {
mutex_unlock(&priv->acpi_lock);
return -EBUSY;
}
@@ -1639,6 +1673,16 @@ static bool i801_acpi_is_smbus_ioport(const struct i801_priv *priv,
address <= pci_resource_end(priv->pci_dev, SMBBAR);
}
+static acpi_status
+i801_acpi_do_access(u32 function, acpi_physical_address address,
+ u32 bits, u64 *value)
+{
+ if ((function & ACPI_IO_MASK) == ACPI_READ)
+ return acpi_os_read_port(address, (u32 *)value, bits);
+ else
+ return acpi_os_write_port(address, (u32)*value, bits);
+}
+
static acpi_status
i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
u64 *value, void *handler_context, void *region_context)
@@ -1648,17 +1692,38 @@ i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
acpi_status status;
/*
- * Once BIOS AML code touches the OpRegion we warn and inhibit any
- * further access from the driver itself. This device is now owned
- * by the system firmware.
+ * Non-i801 accesses pass through.
*/
- mutex_lock(&priv->acpi_lock);
+ if (!i801_acpi_is_smbus_ioport(priv, address))
+ return i801_acpi_do_access(function, address, bits, value);
- if (!priv->acpi_reserved && i801_acpi_is_smbus_ioport(priv, address)) {
- priv->acpi_reserved = true;
+ if (!mutex_trylock(&priv->acpi_lock)) {
+ mutex_lock(&priv->acpi_lock);
+ /*
+ * This better be a read of the status register to acquire
+ * the lock...
+ */
+ if (!priv->acpi_unsafe &&
+ !(address == SMBHSTSTS(priv) &&
+ (function & ACPI_IO_MASK) == ACPI_READ)) {
+ /*
+ * Uh-oh, ACPI AML is trying to do something with the
+ * controller without locking it properly.
+ */
+ priv->acpi_unsafe = true;
+
+ dev_warn(&pdev->dev, "BIOS uses SMBus unsafely\n");
+ dev_warn(&pdev->dev,
+ "Driver SMBus register access inhibited\n");
+ }
+ }
- dev_warn(&pdev->dev, "BIOS is accessing SMBus registers\n");
- dev_warn(&pdev->dev, "Driver SMBus register access inhibited\n");
+ if (!priv->acpi_usage) {
+ priv->acpi_usage = true;
+
+ if (!priv->acpi_unsafe)
+ dev_info(&pdev->dev,
+ "SMBus controller is shared with ACPI AML. This seems safe so far.\n");
/*
* BIOS is accessing the host controller so prevent it from
@@ -1667,10 +1732,7 @@ i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
pm_runtime_get_sync(&pdev->dev);
}
- if ((function & ACPI_IO_MASK) == ACPI_READ)
- status = acpi_os_read_port(address, (u32 *)value, bits);
- else
- status = acpi_os_write_port(address, (u32)*value, bits);
+ status = i801_acpi_do_access(function, address, bits, value);
mutex_unlock(&priv->acpi_lock);
@@ -1706,7 +1768,7 @@ static void i801_acpi_remove(struct i801_priv *priv)
ACPI_ADR_SPACE_SYSTEM_IO, i801_acpi_io_handler);
mutex_lock(&priv->acpi_lock);
- if (priv->acpi_reserved)
+ if (priv->acpi_usage)
pm_runtime_put(&priv->pci_dev->dev);
mutex_unlock(&priv->acpi_lock);
}
--
2.32.0
From: Xiu Jianfeng <xiujianfeng(a)huawei.com>
[ Upstream commit 51dd64bb99e4478fc5280171acd8e1b529eadaf7 ]
This reverts commit ccf11dbaa07b328fa469415c362d33459c140a37.
Commit ccf11dbaa07b ("evm: Fix memleak in init_desc") said there is
memleak in init_desc. That may be incorrect, as we can see, tmp_tfm is
saved in one of the two global variables hmac_tfm or evm_tfm[hash_algo],
then if init_desc is called next time, there is no need to alloc tfm
again, so in the error path of kmalloc desc or crypto_shash_init(desc),
It is not a problem without freeing tmp_tfm.
And also that commit did not reset the global variable to NULL after
freeing tmp_tfm and this makes *tfm a dangling pointer which may cause a
UAF issue.
Reported-by: Guozihua (Scott) <guozihua(a)huawei.com>
Signed-off-by: Xiu Jianfeng <xiujianfeng(a)huawei.com>
Signed-off-by: Mimi Zohar <zohar(a)linux.ibm.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
---
security/integrity/evm/evm_crypto.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index a6dd47eb086d..168c3b78ac47 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -73,7 +73,7 @@ static struct shash_desc *init_desc(char type, uint8_t hash_algo)
{
long rc;
const char *algo;
- struct crypto_shash **tfm, *tmp_tfm = NULL;
+ struct crypto_shash **tfm, *tmp_tfm;
struct shash_desc *desc;
if (type == EVM_XATTR_HMAC) {
@@ -118,16 +118,13 @@ static struct shash_desc *init_desc(char type, uint8_t hash_algo)
alloc:
desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(*tfm),
GFP_KERNEL);
- if (!desc) {
- crypto_free_shash(tmp_tfm);
+ if (!desc)
return ERR_PTR(-ENOMEM);
- }
desc->tfm = *tfm;
rc = crypto_shash_init(desc);
if (rc) {
- crypto_free_shash(tmp_tfm);
kfree(desc);
return ERR_PTR(rc);
}
--
2.35.1
This is the start of the stable review cycle for the 4.19.253 release.
There are 48 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Thu, 21 Jul 2022 11:43:40 +0000.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.19.253-r…
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-4.19.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Linux 4.19.253-rc1
Marc Kleine-Budde <mkl(a)pengutronix.de>
can: m_can: m_can_tx_handler(): fix use after free of skb
Ilpo Järvinen <ilpo.jarvinen(a)linux.intel.com>
serial: pl011: UPSTAT_AUTORTS requires .throttle/unthrottle
Ilpo Järvinen <ilpo.jarvinen(a)linux.intel.com>
serial: stm32: Clear prev values before setting RTS delays
Yi Yang <yiyang13(a)huawei.com>
serial: 8250: fix return error code in serial8250_request_std_resource()
Chanho Park <chanho61.park(a)samsung.com>
tty: serial: samsung_tty: set dma burst_size to 1
Thinh Nguyen <Thinh.Nguyen(a)synopsys.com>
usb: dwc3: gadget: Fix event pending check
Linyu Yuan <quic_linyyuan(a)quicinc.com>
usb: typec: add missing uevent when partner support PD
Lucien Buchmann <lucien.buchmann(a)gmx.net>
USB: serial: ftdi_sio: add Belimo device ids
Linus Torvalds <torvalds(a)linux-foundation.org>
signal handling: don't use BUG_ON() for debugging
Gabriel Fernandez <gabriel.fernandez(a)foss.st.com>
ARM: dts: stm32: use the correct clock source for CEC on stm32mp151
Juergen Gross <jgross(a)suse.com>
x86: Clear .brk area at early boot
Stafford Horne <shorne(a)gmail.com>
irqchip: or1k-pic: Undefine mask_ack for level triggered hardware
Charles Keepax <ckeepax(a)opensource.cirrus.com>
ASoC: wm5110: Fix DRE control
Mark Brown <broonie(a)kernel.org>
ASoC: ops: Fix off by one in range control validation
Jianglei Nie <niejianglei2021(a)163.com>
net: sfp: fix memory leak in sfp_probe()
Michael Walle <michael(a)walle.cc>
NFC: nxp-nci: don't print header length mismatch on i2c error
Hangyu Hua <hbh25y(a)gmail.com>
net: tipc: fix possible refcount leak in tipc_sk_create()
Kai-Heng Feng <kai.heng.feng(a)canonical.com>
platform/x86: hp-wmi: Ignore Sanitization Mode event
Liang He <windhl(a)126.com>
cpufreq: pmac32-cpufreq: Fix refcount leak bug
Florian Westphal <fw(a)strlen.de>
netfilter: br_netfilter: do not skip all hooks with 0 priority
Stephan Gerhold <stephan.gerhold(a)kernkonzept.com>
virtio_mmio: Restore guest page size on resume
Stephan Gerhold <stephan.gerhold(a)kernkonzept.com>
virtio_mmio: Add missing PM calls to freeze/restore
Íñigo Huguet <ihuguet(a)redhat.com>
sfc: fix kernel panic when creating VF
Andrea Mayer <andrea.mayer(a)uniroma2.it>
seg6: bpf: fix skb checksum in bpf_push_seg6_encap()
Andrea Mayer <andrea.mayer(a)uniroma2.it>
seg6: fix skb checksum in SRv6 End.B6 and End.B6.Encaps behaviors
Andrea Mayer <andrea.mayer(a)uniroma2.it>
seg6: fix skb checksum evaluation in SRH encapsulation/insertion
Íñigo Huguet <ihuguet(a)redhat.com>
sfc: fix use after free when disabling sriov
Kuniyuki Iwashima <kuniyu(a)amazon.com>
ipv4: Fix data-races around sysctl_ip_dynaddr.
Kuniyuki Iwashima <kuniyu(a)amazon.com>
icmp: Fix a data-race around sysctl_icmp_ratemask.
Kuniyuki Iwashima <kuniyu(a)amazon.com>
icmp: Fix a data-race around sysctl_icmp_ratelimit.
Michal Suchanek <msuchanek(a)suse.de>
ARM: dts: sunxi: Fix SPI NOR campatible on Orange Pi Zero
Kuniyuki Iwashima <kuniyu(a)amazon.com>
icmp: Fix data-races around sysctl.
Kuniyuki Iwashima <kuniyu(a)amazon.com>
cipso: Fix data-races around sysctl.
Kuniyuki Iwashima <kuniyu(a)amazon.com>
net: Fix data-races around sysctl_mem.
Kuniyuki Iwashima <kuniyu(a)amazon.com>
inetpeer: Fix data-races around sysctl.
Francesco Dolcini <francesco.dolcini(a)toradex.com>
ASoC: sgtl5000: Fix noise on shutdown/remove
Ard Biesheuvel <ardb(a)kernel.org>
ARM: 9209/1: Spectre-BHB: avoid pr_info() every time a CPU comes out of idle
Kris Bahnsen <kris(a)embeddedTS.com>
ARM: dts: imx6qdl-ts7970: Fix ngpio typo and count
Ryusuke Konishi <konishi.ryusuke(a)gmail.com>
nilfs2: fix incorrect masking of permission flags for symlinks
Tejun Heo <tj(a)kernel.org>
cgroup: Use separate src/dst nodes when preloading css_sets for migration
Ard Biesheuvel <ardb(a)kernel.org>
ARM: 9214/1: alignment: advance IT state after emulating Thumb instruction
Dmitry Osipenko <dmitry.osipenko(a)collabora.com>
ARM: 9213/1: Print message about disabled Spectre workarounds only once
Steven Rostedt (Google) <rostedt(a)goodmis.org>
net: sock: tracing: Fix sock_exceed_buf_limit not to dereference stale pointer
Zheng Yejian <zhengyejian1(a)huawei.com>
tracing/histograms: Fix memory leak problem
Juergen Gross <jgross(a)suse.com>
xen/netback: avoid entering xenvif_rx_next_skb() with an empty rx queue
Meng Tang <tangmeng(a)uniontech.com>
ALSA: hda/realtek - Fix headset mic problem for a HP machine with alc221
Meng Tang <tangmeng(a)uniontech.com>
ALSA: hda/conexant: Apply quirk for another HP ProDesk 600 G3 model
Meng Tang <tangmeng(a)uniontech.com>
ALSA: hda - Add fixup for Dell Latitidue E5430
-------------
Diffstat:
Documentation/networking/ip-sysctl.txt | 4 +--
Makefile | 4 +--
arch/arm/boot/dts/imx6qdl-ts7970.dtsi | 2 +-
arch/arm/boot/dts/stm32mp157c.dtsi | 2 +-
arch/arm/boot/dts/sun8i-h2-plus-orangepi-zero.dts | 2 +-
arch/arm/include/asm/ptrace.h | 26 ++++++++++++++++
arch/arm/mm/alignment.c | 3 ++
arch/arm/mm/proc-v7-bugs.c | 9 +++---
arch/arm/probes/decode.h | 26 +---------------
arch/x86/kernel/head64.c | 2 ++
drivers/cpufreq/pmac32-cpufreq.c | 4 +++
drivers/irqchip/irq-or1k-pic.c | 1 -
drivers/net/can/m_can/m_can.c | 5 +--
drivers/net/ethernet/sfc/ef10.c | 3 ++
drivers/net/ethernet/sfc/ef10_sriov.c | 10 ++++--
drivers/net/phy/sfp.c | 2 +-
drivers/net/xen-netback/rx.c | 1 +
drivers/nfc/nxp-nci/i2c.c | 8 +++--
drivers/platform/x86/hp-wmi.c | 3 ++
drivers/tty/serial/8250/8250_port.c | 4 ++-
drivers/tty/serial/amba-pl011.c | 23 ++++++++++++--
drivers/tty/serial/samsung.c | 5 ++-
drivers/tty/serial/stm32-usart.c | 2 ++
drivers/usb/dwc3/gadget.c | 4 ++-
drivers/usb/serial/ftdi_sio.c | 3 ++
drivers/usb/serial/ftdi_sio_ids.h | 6 ++++
drivers/usb/typec/class.c | 1 +
drivers/virtio/virtio_mmio.c | 26 ++++++++++++++++
fs/nilfs2/nilfs.h | 3 ++
include/linux/cgroup-defs.h | 3 +-
include/net/sock.h | 2 +-
include/trace/events/sock.h | 6 ++--
kernel/cgroup/cgroup.c | 37 ++++++++++++++---------
kernel/signal.c | 8 ++---
kernel/trace/trace_events_hist.c | 2 ++
net/bridge/br_netfilter_hooks.c | 21 +++++++++++--
net/core/filter.c | 1 -
net/ipv4/af_inet.c | 4 +--
net/ipv4/cipso_ipv4.c | 12 +++++---
net/ipv4/icmp.c | 10 +++---
net/ipv4/inetpeer.c | 12 +++++---
net/ipv6/seg6_iptunnel.c | 5 ++-
net/ipv6/seg6_local.c | 2 --
net/tipc/socket.c | 1 +
sound/pci/hda/patch_conexant.c | 1 +
sound/pci/hda/patch_realtek.c | 13 ++++++++
sound/soc/codecs/sgtl5000.c | 9 ++++++
sound/soc/codecs/sgtl5000.h | 1 +
sound/soc/codecs/wm5110.c | 8 +++--
sound/soc/soc-ops.c | 4 +--
50 files changed, 255 insertions(+), 101 deletions(-)
The lockdown LSM is primarily used in conjunction with UEFI Secure Boot.
This LSM may also be used on machines without UEFI. It can also be enabled
when UEFI Secure Boot is disabled. One of lockdown's features is to prevent
kexec from loading untrusted kernels. Lockdown can be enabled through a
bootparam or after the kernel has booted through securityfs.
If IMA appraisal is used with the "ima_appraise=log" boot param,
lockdown can be defeated with kexec on any machine when Secure Boot is
disabled or unavailable. IMA prevents setting "ima_appraise=log"
from the boot param when Secure Boot is enabled, but this does not cover
cases where lockdown is used without Secure Boot.
To defeat lockdown, boot without Secure Boot and add ima_appraise=log
to the kernel command line; then:
$ echo "integrity" > /sys/kernel/security/lockdown
$ echo "appraise func=KEXEC_KERNEL_CHECK appraise_type=imasig" > \
/sys/kernel/security/ima/policy
$ kexec -ls unsigned-kernel
Add a call to verify ima appraisal is set to "enforce" whenever lockdown
is enabled. This fixes CVE-2022-21505.
Fixes: 29d3c1c8dfe7 ("kexec: Allow kexec_file() with appropriate IMA policy when locked down")
Signed-off-by: Eric Snowberg <eric.snowberg(a)oracle.com>
Acked-by: Mimi Zohar <zohar(a)linux.ibm.com>
---
security/integrity/ima/ima_policy.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 73917413365b..a8802b8da946 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -2247,6 +2247,10 @@ bool ima_appraise_signature(enum kernel_read_file_id id)
if (id >= READING_MAX_ID)
return false;
+ if (id == READING_KEXEC_IMAGE && !(ima_appraise & IMA_APPRAISE_ENFORCE)
+ && security_locked_down(LOCKDOWN_KEXEC))
+ return false;
+
func = read_idmap[id] ?: FILE_CHECK;
rcu_read_lock();
--
2.27.0
From: Jinke Han <hanjinke.666(a)bytedance.com>
In our test of iocost, we encounttered some list add/del corrutions of
inner_walk list in ioc_timer_fn.
The reason can be descripted as follow:
cpu 0 cpu 1
ioc_qos_write ioc_qos_write
ioc = q_to_ioc(bdev_get_queue(bdev));
if (!ioc) {
ioc = kzalloc(); ioc = q_to_ioc(bdev_get_queue(bdev));
if (!ioc) {
ioc = kzalloc();
...
rq_qos_add(q, rqos);
}
...
rq_qos_add(q, rqos);
...
}
When the io.cost.qos file is written by two cpu concurrently, rq_qos may
be added to one disk twice. In that case, there will be two iocs enabled
and running on one disk. They own different iocgs on their active list.
In the ioc_timer_fn function, because of the iocgs from two ioc have the
same root iocg, the root iocg's walk_list may be overwritten by each
other and this lead to list add/del corrutions in building or destorying
the inner_walk list.
And so far, the blk-rq-qos framework works in case that one instance for
one type rq_qos per queue by default. This patch make this explicit and
also fix the crash above.
Signed-off-by: Jinke Han <hanjinke.666(a)bytedance.com>
Reviewed-by: Muchun Song <songmuchun(a)bytedance.com>
Acked-by: Tejun Heo <tj(a)kernel.org>
Cc: <stable(a)vger.kernel.org>
---
Changes in v2:
-use goto in incost and rename the ebusy label
Changes in v3
-use goto in all place
block/blk-iocost.c | 20 +++++++++++++-------
block/blk-iolatency.c | 18 +++++++++++-------
block/blk-ioprio.c | 15 +++++++++++----
block/blk-rq-qos.h | 11 ++++++++++-
block/blk-wbt.c | 12 +++++++++++-
5 files changed, 56 insertions(+), 20 deletions(-)
diff --git a/block/blk-iocost.c b/block/blk-iocost.c
index 33a11ba971ea..c6181357e545 100644
--- a/block/blk-iocost.c
+++ b/block/blk-iocost.c
@@ -2886,15 +2886,21 @@ static int blk_iocost_init(struct request_queue *q)
* called before policy activation completion, can't assume that the
* target bio has an iocg associated and need to test for NULL iocg.
*/
- rq_qos_add(q, rqos);
+ ret = rq_qos_add(q, rqos);
+ if (ret)
+ goto err_free_ioc;
+
ret = blkcg_activate_policy(q, &blkcg_policy_iocost);
- if (ret) {
- rq_qos_del(q, rqos);
- free_percpu(ioc->pcpu_stat);
- kfree(ioc);
- return ret;
- }
+ if (ret)
+ goto err_del_qos;
return 0;
+
+err_del_qos:
+ rq_qos_del(q, rqos);
+err_free_ioc:
+ free_percpu(ioc->pcpu_stat);
+ kfree(ioc);
+ return ret;
}
static struct blkcg_policy_data *ioc_cpd_alloc(gfp_t gfp)
diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c
index 9568bf8dfe82..7845dca5fcfd 100644
--- a/block/blk-iolatency.c
+++ b/block/blk-iolatency.c
@@ -773,19 +773,23 @@ int blk_iolatency_init(struct request_queue *q)
rqos->ops = &blkcg_iolatency_ops;
rqos->q = q;
- rq_qos_add(q, rqos);
-
+ ret = rq_qos_add(q, rqos);
+ if (ret)
+ goto err_free;
ret = blkcg_activate_policy(q, &blkcg_policy_iolatency);
- if (ret) {
- rq_qos_del(q, rqos);
- kfree(blkiolat);
- return ret;
- }
+ if (ret)
+ goto err_qos_del;
timer_setup(&blkiolat->timer, blkiolatency_timer_fn, 0);
INIT_WORK(&blkiolat->enable_work, blkiolatency_enable_work_fn);
return 0;
+
+err_qos_del:
+ rq_qos_del(q, rqos);
+err_free:
+ kfree(blkiolat);
+ return ret;
}
static void iolatency_set_min_lat_nsec(struct blkcg_gq *blkg, u64 val)
diff --git a/block/blk-ioprio.c b/block/blk-ioprio.c
index 79e797f5d194..528d3ffcd0ef 100644
--- a/block/blk-ioprio.c
+++ b/block/blk-ioprio.c
@@ -235,10 +235,8 @@ int blk_ioprio_init(struct request_queue *q)
return -ENOMEM;
ret = blkcg_activate_policy(q, &ioprio_policy);
- if (ret) {
- kfree(blkioprio_blkg);
- return ret;
- }
+ if (ret)
+ goto err_free;
rqos = &blkioprio_blkg->rqos;
rqos->id = RQ_QOS_IOPRIO;
@@ -251,8 +249,17 @@ int blk_ioprio_init(struct request_queue *q)
* rq-qos callbacks.
*/
rq_qos_add(q, rqos);
+ if (ret)
+ goto err_deactivate_policy;
return 0;
+
+err_deactivate_policy:
+ blkcg_deactivate_policy(q, &ioprio_policy);
+err_free:
+ kfree(blkioprio_blkg);
+ return ret;
+
}
static int __init ioprio_init(void)
diff --git a/block/blk-rq-qos.h b/block/blk-rq-qos.h
index 0e46052b018a..08b856570ad1 100644
--- a/block/blk-rq-qos.h
+++ b/block/blk-rq-qos.h
@@ -86,7 +86,7 @@ static inline void rq_wait_init(struct rq_wait *rq_wait)
init_waitqueue_head(&rq_wait->wait);
}
-static inline void rq_qos_add(struct request_queue *q, struct rq_qos *rqos)
+static inline int rq_qos_add(struct request_queue *q, struct rq_qos *rqos)
{
/*
* No IO can be in-flight when adding rqos, so freeze queue, which
@@ -98,6 +98,8 @@ static inline void rq_qos_add(struct request_queue *q, struct rq_qos *rqos)
blk_mq_freeze_queue(q);
spin_lock_irq(&q->queue_lock);
+ if (rq_qos_id(q, rqos->id))
+ goto ebusy;
rqos->next = q->rq_qos;
q->rq_qos = rqos;
spin_unlock_irq(&q->queue_lock);
@@ -109,6 +111,13 @@ static inline void rq_qos_add(struct request_queue *q, struct rq_qos *rqos)
blk_mq_debugfs_register_rqos(rqos);
mutex_unlock(&q->debugfs_mutex);
}
+
+ return 0;
+ebusy:
+ spin_unlock_irq(&q->queue_lock);
+ blk_mq_unfreeze_queue(q);
+ return -EBUSY;
+
}
static inline void rq_qos_del(struct request_queue *q, struct rq_qos *rqos)
diff --git a/block/blk-wbt.c b/block/blk-wbt.c
index 0c119be0e813..ae6ea0b54579 100644
--- a/block/blk-wbt.c
+++ b/block/blk-wbt.c
@@ -820,6 +820,7 @@ int wbt_init(struct request_queue *q)
{
struct rq_wb *rwb;
int i;
+ int ret;
rwb = kzalloc(sizeof(*rwb), GFP_KERNEL);
if (!rwb)
@@ -846,7 +847,10 @@ int wbt_init(struct request_queue *q)
/*
* Assign rwb and add the stats callback.
*/
- rq_qos_add(q, &rwb->rqos);
+ ret = rq_qos_add(q, &rwb->rqos);
+ if (ret)
+ goto err_free;
+
blk_stat_add_callback(q, rwb->cb);
rwb->min_lat_nsec = wbt_default_latency_nsec(q);
@@ -855,4 +859,10 @@ int wbt_init(struct request_queue *q)
wbt_set_write_cache(q, test_bit(QUEUE_FLAG_WC, &q->queue_flags));
return 0;
+
+err_free:
+ blk_stat_free_callback(rwb->cb);
+ kfree(rwb);
+ return ret;
+
}
--
2.20.1