1
0
mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2026-01-11 17:10:13 +00:00

Compare commits

...

28 Commits

Author SHA1 Message Date
Linus Torvalds
8f0b4cce44 Linux 6.19-rc1 2025-12-14 16:05:07 +12:00
Linus Torvalds
6a1636e066 SCSI misc on 20251214
The only core fix is in doc; all the others are in drivers, with the
 biggest impacts in libsas being the rollback on error handling and in
 ufs coming from a couple of error handling fixes, one causing a crash
 if it's activated before scanning and the other fixing W-LUN
 resumption.
 
 Signed-off-by: James E.J. Bottomley <James.Bottomley@HansenPartnership.com>
 -----BEGIN PGP SIGNATURE-----
 
 iLgEABMIAGAWIQTnYEDbdso9F2cI+arnQslM7pishQUCaT4RWBsUgAAAAAAEAA5t
 YW51MiwyLjUrMS4xMSwyLDImHGphbWVzLmJvdHRvbWxleUBoYW5zZW5wYXJ0bmVy
 c2hpcC5jb20ACgkQ50LJTO6YrIVfSgEA23oY0kPjLLkNj4KAjLoWVPmZ/5efKw49
 m6YUwfvzTS8BAIq4eFHVecwAM8FAe9NwuOKgO5d9u6epAy6wzBeP2jly
 =cpHq
 -----END PGP SIGNATURE-----

Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI fixes from James Bottomley:
 "The only core fix is in doc; all the others are in drivers, with the
  biggest impacts in libsas being the rollback on error handling and in
  ufs coming from a couple of error handling fixes, one causing a crash
  if it's activated before scanning and the other fixing W-LUN
  resumption"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: ufs: qcom: Fix confusing cleanup.h syntax
  scsi: libsas: Add rollback handling when an error occurs
  scsi: device_handler: Return error pointer in scsi_dh_attached_handler_name()
  scsi: ufs: core: Fix a deadlock in the frequency scaling code
  scsi: ufs: core: Fix an error handler crash
  scsi: Revert "scsi: libsas: Fix exp-attached device scan after probe failure scanned in again after probe failed"
  scsi: ufs: core: Fix RPMB link error by reversing Kconfig dependencies
  scsi: qla4xxx: Use time conversion macros
  scsi: qla2xxx: Enable/disable IRQD_NO_BALANCING during reset
  scsi: ipr: Enable/disable IRQD_NO_BALANCING during reset
  scsi: imm: Fix use-after-free bug caused by unfinished delayed work
  scsi: target: sbp: Remove KMSG_COMPONENT macro
  scsi: core: Correct documentation for scsi_device_quiesce()
  scsi: mpi3mr: Prevent duplicate SAS/SATA device entries in channel 1
  scsi: target: Reset t_task_cdb pointer in error case
  scsi: ufs: core: Fix EH failure after W-LUN resume error
2025-12-14 15:35:35 +12:00
Linus Torvalds
0dfb36b2dc We have a patch that adds an initial set of tracepoints to the MDS
client from Max, a fix that hardens osdmap parsing code from myself
 (marked for stable) and a few assorted fixups.
 -----BEGIN PGP SIGNATURE-----
 
 iQFHBAABCAAxFiEEydHwtzie9C7TfviiSn/eOAIR84sFAmk8YxITHGlkcnlvbW92
 QGdtYWlsLmNvbQAKCRBKf944AhHzi702B/9Mfj0HQSAaWCyMz6GJAv8+1ijVTSbG
 nTFeMmipYZhPn188OvWqHsf1cw9rWY0fzenIEW05Tk3YmMvYdeRmCcOkZdeG06xw
 um8XxX4L8315E0b98CCpQpVa02ux7XoNtBPjeHccl8PEErJQgQJrQ3Cc/C8kk5U5
 a0KlfeVRXYWkOPJva3+wosOu0t9QgJ9ABt5stqcvYDfdkKfvatQMBN3N1nNRKkFH
 yhNPv+nRtypSk8jiHhKeeCVmosC0L7MnKuO593vDr761cY5mKrgKFqc2LLlPF6r0
 /p13s5SG6X38RUegWCjcK4XRJAzVcR/tyod8LkVVp8d5DC/ptcyy8H+I
 =h1gC
 -----END PGP SIGNATURE-----

Merge tag 'ceph-for-6.19-rc1' of https://github.com/ceph/ceph-client

Pull ceph updates from Ilya Dryomov:
 "We have a patch that adds an initial set of tracepoints to the MDS
  client from Max, a fix that hardens osdmap parsing code from myself
  (marked for stable) and a few assorted fixups"

* tag 'ceph-for-6.19-rc1' of https://github.com/ceph/ceph-client:
  rbd: stop selecting CRC32, CRYPTO, and CRYPTO_AES
  ceph: stop selecting CRC32, CRYPTO, and CRYPTO_AES
  libceph: make decode_pool() more resilient against corrupted osdmaps
  libceph: Amend checking to fix `make W=1` build breakage
  ceph: Amend checking to fix `make W=1` build breakage
  ceph: add trace points to the MDS client
  libceph: fix log output race condition in OSD client
2025-12-14 15:24:10 +12:00
Linus Torvalds
4cfc21494a Trivial optimization.
Davidlohr Bueso (1):
   tomoyo: Use local kmap in tomoyo_dump_page()
 
  security/tomoyo/domain.c |    9 ++-------
  1 file changed, 2 insertions(+), 7 deletions(-)
 -----BEGIN PGP SIGNATURE-----
 
 iQJXBAABCABBFiEEQ8gzaWI9etOpbC/HQl8SjQxk9SoFAmk76TkjHHBlbmd1aW4t
 a2VybmVsQGktbG92ZS5zYWt1cmEubmUuanAACgkQQl8SjQxk9Sojjg/+LruNwzbV
 mpvoPw0uIMtPAvVMwzhN93bSAZrxW40ANF4+c5Oo/bLlHAjFGLbYI6sE7leKbwUd
 K5iuEJ+t0TohdcN7EbfmY/DDZGPy4JymlLRFgwxKZq2v3aj85eSCCF2vCpXyKeOo
 HEu6k87xPTOOY9/691C6cDUsqIOOygF78gJWa9hLeDGMhc/t6Oi/bcy417HMMLsv
 Z5z15Jfj4katid+245aMLRcqShtomiRF0VCY9M1QX1G+1bwSjPqQhhF6ckgIjk/K
 C/gMP9xK9cd1OwGhSyKS4eRtfT6vuSi0e/uNyvm39miuFolwj6spyQkXJ3mcYcUS
 u2ggrsPOYat5jE5OLGcvXVgUAuw0ZatBAPzdAiWQCjhXVxTRArz+VJzUZraL/oPM
 LLn7OMK/T3ajxNbIqIbtFcoIKClM/jrZmCTFHFH6/uVmqOo8OsoetOY3yPw6yq9n
 Y/1kFczOtqLTTa0meWT35Ea/AFVQX59h2wsN3ZvkF5Fp9hf0uNnuesPOjwT+7y3U
 TjvAqemfI/HXogHvpF7qlQYHSjUZVsyjZgZxgzYS9LFZU4O7h1WnNxqCEIJOauzi
 m2rI/N0NVe3lKtn46K79lxsqCEBY9c3CtaQJEzx3JOKcK9db+NtN0ho1ztQ3ZfmC
 SP42iWDv0tYgmTc81Sz70h7B7SM8Vf6KoeI=
 =wGTk
 -----END PGP SIGNATURE-----

Merge tag 'tomoyo-pr-20251212' of git://git.code.sf.net/p/tomoyo/tomoyo

Pull tomoyo update from Tetsuo Handa:
 "Trivial optimization"

* tag 'tomoyo-pr-20251212' of git://git.code.sf.net/p/tomoyo/tomoyo:
  tomoyo: Use local kmap in tomoyo_dump_page()
2025-12-14 15:21:02 +12:00
Ilya Dryomov
21c1466ea2 rbd: stop selecting CRC32, CRYPTO, and CRYPTO_AES
None of the RBD code directly requires CRC32, CRYPTO, or CRYPTO_AES.
These options are needed by CEPH_LIB code and they are selected there
directly.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Reviewed-by: Dongsheng Yang <dongsheng.yang@linux.dev>
2025-12-10 11:50:54 +01:00
Eric Biggers
3680fc138e ceph: stop selecting CRC32, CRYPTO, and CRYPTO_AES
None of the CEPH_FS code directly requires CRC32, CRYPTO, or CRYPTO_AES.
These options do get selected indirectly anyway via CEPH_LIB, which does
need them, but there is no need for CEPH_FS to select them too.

Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
2025-12-10 11:50:54 +01:00
Ilya Dryomov
8c73851271 libceph: make decode_pool() more resilient against corrupted osdmaps
If the osdmap is (maliciously) corrupted such that the encoded length
of ceph_pg_pool envelope is less than what is expected for a particular
encoding version, out-of-bounds reads may ensue because the only bounds
check that is there is based on that length value.

This patch adds explicit bounds checks for each field that is decoded
or skipped.

Cc: stable@vger.kernel.org
Reported-by: ziming zhang <ezrakiez@gmail.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Reviewed-by: Xiubo Li <xiubli@redhat.com>
Tested-by: ziming zhang <ezrakiez@gmail.com>
2025-12-10 11:50:54 +01:00
Andy Shevchenko
04d8712b07 libceph: Amend checking to fix make W=1 build breakage
In a few cases the code compares 32-bit value to a SIZE_MAX derived
constant which is much higher than that value on 64-bit platforms,
Clang, in particular, is not happy about this

net/ceph/osdmap.c:1441:10: error: result of comparison of constant 4611686018427387891 with expression of type 'u32' (aka 'unsigned int') is always false [-Werror,-Wtautological-constant-out-of-range-compare]
 1441 |         if (len > (SIZE_MAX - sizeof(*pg)) / sizeof(u32))
      |             ~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
net/ceph/osdmap.c:1624:10: error: result of comparison of constant 2305843009213693945 with expression of type 'u32' (aka 'unsigned int') is always false [-Werror,-Wtautological-constant-out-of-range-compare]
 1624 |         if (len > (SIZE_MAX - sizeof(*pg)) / (2 * sizeof(u32)))
      |             ~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Fix this by casting to size_t. Note, that possible replacement of SIZE_MAX
by U32_MAX may lead to the behaviour changes on the corner cases.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
2025-12-10 11:50:54 +01:00
Andy Shevchenko
87327d4eaa ceph: Amend checking to fix make W=1 build breakage
In a few cases the code compares 32-bit value to a SIZE_MAX derived
constant which is much higher than that value on 64-bit platforms,
Clang, in particular, is not happy about this

fs/ceph/snap.c:377:10: error: result of comparison of constant 2305843009213693948 with expression of type 'u32' (aka 'unsigned int') is always false [-Werror,-Wtautological-constant-out-of-range-compare]
  377 |         if (num > (SIZE_MAX - sizeof(*snapc)) / sizeof(u64))
      |             ~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Fix this by casting to size_t. Note, that possible replacement of SIZE_MAX
by U32_MAX may lead to the behaviour changes on the corner cases.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
2025-12-10 11:50:54 +01:00
Max Kellermann
d927a595ab ceph: add trace points to the MDS client
This patch adds trace points to the Ceph filesystem MDS client:

- request submission (CEPH_MSG_CLIENT_REQUEST) and completion
  (CEPH_MSG_CLIENT_REPLY)
- capabilities (CEPH_MSG_CLIENT_CAPS)

These are the central pieces that are useful for analyzing MDS
latency/performance problems from the client's perspective.

In the long run, all doutc() calls should be replaced with
tracepoints.  This way, the Ceph filesystem can be traced at any time
(without spamming the kernel log).  Additionally, trace points can be
used in BPF programs (which can even deference the pointer parameters
and extract more values).

Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
2025-12-10 11:50:54 +01:00
Simon Buttgereit
d6c2f41eb9 libceph: fix log output race condition in OSD client
OSD client logging has a problem in get_osd() and put_osd().
For one logging output refcount_read() is called twice. If recount
value changes between both calls logging output is not consistent.

This patch prints out only the resulting value.

[ idryomov: don't make the log messages more verbose ]

Signed-off-by: Simon Buttgereit <simon.buttgereit@tu-ilmenau.de>
Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
2025-12-10 11:50:53 +01:00
Krzysztof Kozlowski
946574434a scsi: ufs: qcom: Fix confusing cleanup.h syntax
Initializing automatic __free variables to NULL without need (e.g.
branches with different allocations), followed by actual allocation is
in contrary to explicit coding rules guiding cleanup.h:

"Given that the "__free(...) = NULL" pattern for variables defined at
the top of the function poses this potential interdependency problem the
recommendation is to always define and assign variables in one statement
and not group variable definitions at the top of the function when
__free() is used."

Code does not have a bug, but is less readable and uses discouraged
coding practice, so fix that by moving declaration to the place of
assignment.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Link: https://patch.msgid.link/20251208020807.5043-2-krzysztof.kozlowski@oss.qualcomm.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-12-08 22:11:00 -05:00
Chaohai Chen
362432e9b9 scsi: libsas: Add rollback handling when an error occurs
In sas_register_phys(), if an error is triggered in the loop process, we
need to roll back the resources that have already been requested.

Add sas_unregister_phys() when an error occurs in sas_register_ha().

[mkp: a few coding style tweaks and address John's comment]

Signed-off-by: Chaohai Chen <wdhh6@aliyun.com>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Link: https://patch.msgid.link/20251206060616.69216-1-wdhh6@aliyun.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-12-08 22:08:31 -05:00
Benjamin Marzinski
fd81bc5cca scsi: device_handler: Return error pointer in scsi_dh_attached_handler_name()
If scsi_dh_attached_handler_name() fails to allocate the handler name,
dm-multipath (its only caller) assumes there is no attached device
handler, and sets the device up incorrectly. Return an error pointer
instead, so multipath can distinguish between failure, success where
there is no attached device handler, or when the path device is not a
SCSI device at all.

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Reviewed-by: Martin Wilck <mwilck@suse.com>
Link: https://patch.msgid.link/20251206010015.1595225-1-bmarzins@redhat.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-12-08 22:04:38 -05:00
Bart Van Assche
d2875b812b scsi: ufs: core: Fix a deadlock in the frequency scaling code
Commit 08b12cda6c44 ("scsi: ufs: core: Switch to scsi_get_internal_cmd()")
accidentally introduced a deadlock in the frequency scaling code.
ufshcd_clock_scaling_unprepare() may submit a device management command
while SCSI command processing is blocked. The deadlock was introduced by
using the SCSI core for submitting device management commands
(scsi_get_internal_cmd() + blk_execute_rq()). Fix this deadlock by calling
blk_mq_unquiesce_tagset() before any device management commands are
submitted by ufshcd_clock_scaling_unprepare().

Fixes: 08b12cda6c44 ("scsi: ufs: core: Switch to scsi_get_internal_cmd()")
Reported-by: Manivannan Sadhasivam <mani@kernel.org>
Reported-by: Roger Shimizu <rosh@debian.org>
Closes: https://lore.kernel.org/linux-scsi/ehorjaflathzab5oekx2nae2zss5vi2r36yqkqsfjb2fgsifz2@yk3us5g3igow/
Tested-by: Roger Shimizu <rosh@debian.org>
Cc: Nitin Rawat <nitin.rawat@oss.qualcomm.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Reviewed-by: Nitin Rawat <nitin.rawat@oss.qualcomm.com>
Tested-by: Alexey Klimov <alexey.klimov@linaro.org> # RB5 board
Link: https://patch.msgid.link/20251204181548.1006696-1-bvanassche@acm.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-12-08 21:58:28 -05:00
Bart Van Assche
14be351e5c scsi: ufs: core: Fix an error handler crash
The UFS error handler may be activated before SCSI scanning has started
and hence before hba->ufs_device_wlun has been set. Check the
hba->ufs_device_wlun pointer before using it.

Cc: Peter Wang <peter.wang@mediatek.com>
Cc: Nitin Rawat <nitin.rawat@oss.qualcomm.com>
Fixes: e23ef4f22db3 ("scsi: ufs: core: Fix error handler host_sem issue")
Fixes: f966e02ae521 ("scsi: ufs: core: Fix runtime suspend error deadlock")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Reviewed-by: Nitin Rawat <nitin.rawat@oss.qualcomm.com>
Tested-by: Nitin Rawat <nitin.rawat@oss.qualcomm.com> #SM8750
Link: https://patch.msgid.link/20251204170457.994851-1-bvanassche@acm.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-12-08 21:56:33 -05:00
Xingui Yang
278712d20b scsi: Revert "scsi: libsas: Fix exp-attached device scan after probe failure scanned in again after probe failed"
This reverts commit ab2068a6fb84751836a84c26ca72b3beb349619d.

When probing the exp-attached sata device, libsas/libata will issue a
hard reset in sas_probe_sata() -> ata_sas_async_probe(), then a
broadcast event will be received after the disk probe fails, and this
commit causes the probe will be re-executed on the disk, and a faulty
disk may get into an indefinite loop of probe.

Therefore, revert this commit, although it can fix some temporary issues
with disk probe failure.

Signed-off-by: Xingui Yang <yangxingui@huawei.com>
Reviewed-by: Jason Yan <yanaijie@huawei.com>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Link: https://patch.msgid.link/20251202065627.140361-1-yangxingui@huawei.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-12-03 01:36:13 -05:00
Bean Huo
d98b4d52bf scsi: ufs: core: Fix RPMB link error by reversing Kconfig dependencies
When CONFIG_SCSI_UFSHCD=y and CONFIG_RPMB=m, the kernel fails to link
with undefined references to ufs_rpmb_probe() and ufs_rpmb_remove():

  ld: drivers/ufs/core/ufshcd.c:8950: undefined reference to `ufs_rpmb_probe'
  ld: drivers/ufs/core/ufshcd.c:10505: undefined reference to `ufs_rpmb_remove'

The issue is that RPMB depends on its consumers (MMC, UFS) in Kconfig,
which is backwards. This prevents proper module dependency handling when
the library is modular but consumers are built-in.

Fix by reversing the dependency:

 - Remove 'depends on MMC || SCSI_UFSHCD' from RPMB Kconfig

 - Add 'depends on RPMB || !RPMB' to SCSI_UFSHCD Kconfig

This allows RPMB to be an independent library while ensuring correct
linking in all module/built-in combinations.

Fixes: b06b8c421485 ("scsi: ufs: core: Add OP-TEE based RPMB driver for UFS devices")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202511300443.h7sotuL0-lkp@intel.com/
Suggested-by: Arnd Bergmann <arnd@arndb.de>
Cc: Bart Van Assche <bvanassche@acm.org>
Cc: Jens Wiklander <jens.wiklander@linaro.org>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Bean Huo <beanhuo@micron.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20251202155138.2607210-1-beanhuo@iokpp.de
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-12-03 01:33:10 -05:00
Davidlohr Bueso
a9ea3a2e08 tomoyo: Use local kmap in tomoyo_dump_page()
Replace the now deprecated kmap_atomic() with kmap_local_page().

The memcpy does not need atomic semantics, and the removed comment
is now stale - this patch now makes it in sync again. Last but not
least, highmem is going to be removed[0].

Link: https://lore.kernel.org/all/4ff89b72-03ff-4447-9d21-dd6a5fe1550f@app.fastmail.com/ [0]
Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
2025-12-01 23:05:26 +09:00
Shi Hao
9086cac895 scsi: qla4xxx: Use time conversion macros
Replace the raw use of 500 value in schedule_timeout() function with
msecs_to_jiffies() to ensure intended value across different kernel
configurations regardless of HZ value.

Signed-off-by: Shi Hao <i.shihao.999@gmail.com>
Link: https://patch.msgid.link/20251117200949.42557-1-i.shihao.999@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-11-29 16:37:44 -05:00
Wen Xiong
eaea513077 scsi: qla2xxx: Enable/disable IRQD_NO_BALANCING during reset
A dynamic remove/add storage adapter test hits EEH on PowerPC:

  EEH: [c00000000004f77c] __eeh_send_failure_event+0x7c/0x160
  EEH: [c000000000048464] eeh_dev_check_failure.part.0+0x254/0x660
  EEH: [c000000000934e0c] __pci_read_msi_msg+0x1ac/0x280
  EEH: [c000000000100f68] pseries_msi_compose_msg+0x28/0x40
  EEH: [c00000000020e1cc] irq_chip_compose_msi_msg+0x5c/0x90
  EEH: [c000000000214b1c] msi_domain_set_affinity+0xbc/0x100
  EEH: [c000000000206be4] irq_do_set_affinity+0x214/0x2c0
  EEH: [c000000000206e04] irq_set_affinity_locked+0x174/0x230
  EEH: [c000000000207044] irq_set_affinity+0x64/0xa0
  EEH: [c000000000212890] write_irq_affinity.constprop.0.isra.0+0x130/0x150
  EEH: [c00000000068868c] proc_reg_write+0xfc/0x160
  EEH: [c0000000005adb48] vfs_write+0xf8/0x4e0
  EEH: [c0000000005ae234] ksys_write+0x84/0x140
  EEH: [c00000000002e994] system_call_exception+0x164/0x310
  EEH: [c00000000000bfe8] system_call_vectored_common+0xe8/0x278

The irqbalance daemon kicks in before invoking qla2xxx->slot_reset
during the EEH recovery process.

  irqbalance daemon
  ->irq_set_affinity()
  ->msi_domain_set_affinity()
  ->irq_chip_set_affiinity_parent()
  ->xive_irq_set_affinity()
  ->pseries_msi_compose_ms()
  ->__pci_read_msi_msg()
  ->irq_chip_compose_msi_msg()

In __pci_read_msi_msg(), the first MSI-X vector is set to all F by the
irqbalance daemon.  pci_write_msg_msix: index=0, lo=ffffffff hi=fffffff

IRQ balancing is not required during adapter reset.

Enable "IRQ_NO_BALANCING" bit before starting adapter reset and disable
it calling pci_restore_state(). The irqbalance daemon is disabled for
this short period of time (~2s).

Co-developed-by: Kyle Mahlkuch <Kyle.Mahlkuch@ibm.com>
Signed-off-by: Kyle Mahlkuch <Kyle.Mahlkuch@ibm.com>
Signed-off-by: Wen Xiong <wenxiong@linux.ibm.com>
Link: https://patch.msgid.link/20251028142427.3969819-3-wenxiong@linux.ibm.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-11-29 15:56:18 -05:00
Wen Xiong
6ac3484fb1 scsi: ipr: Enable/disable IRQD_NO_BALANCING during reset
A dynamic remove/add storage adapter test hits EEH on PowerPC:

  EEH: [c00000000004f75c] __eeh_send_failure_event+0x7c/0x160
  EEH: [c000000000048444] eeh_dev_check_failure.part.0+0x254/0x650
  EEH: [c008000001650678] eeh_readl+0x60/0x90 [ipr]
  EEH: [c00800000166746c] ipr_cancel_op+0x2b8/0x524 [ipr]
  EEH: [c008000001656524] ipr_eh_abort+0x6c/0x130 [ipr]
  EEH: [c000000000ab0d20] scmd_eh_abort_handler+0x140/0x440
  EEH: [c00000000017e558] process_one_work+0x298/0x590
  EEH: [c00000000017eef8] worker_thread+0xa8/0x620
  EEH: [c00000000018be34] kthread+0x124/0x130
  EEH: [c00000000000cd64] ret_from_kernel_thread+0x5c/0x64

A PCIe bus trace reveals that a vector of MSI-X is cleared to 0 by
irqbalance daemon. If we disable irqbalance daemon, we won't see the
issue.

With debug enabled in ipr driver:

  [   44.103071] ipr: Entering __ipr_remove
  [   44.103083] ipr: Entering ipr_initiate_ioa_bringdown
  [   44.103091] ipr: Entering ipr_reset_shutdown_ioa
  [   44.103099] ipr: Leaving ipr_reset_shutdown_ioa
  [   44.103105] ipr: Leaving ipr_initiate_ioa_bringdown
  [   44.149918] ipr: Entering ipr_reset_ucode_download
  [   44.149935] ipr: Entering ipr_reset_alert
  [   44.150032] ipr: Entering ipr_reset_start_timer
  [   44.150038] ipr: Leaving ipr_reset_alert
  [   44.244343] scsi 1:2:3:0: alua: Detached
  [   44.254300] ipr: Entering ipr_reset_start_bist
  [   44.254320] ipr: Entering ipr_reset_start_timer
  [   44.254325] ipr: Leaving ipr_reset_start_bist
  [   44.364329] scsi 1:2:4:0: alua: Detached
  [   45.134341] scsi 1:2:5:0: alua: Detached
  [   45.860949] ipr: Entering ipr_reset_shutdown_ioa
  [   45.860962] ipr: Leaving ipr_reset_shutdown_ioa
  [   45.860966] ipr: Entering ipr_reset_alert
  [   45.861028] ipr: Entering ipr_reset_start_timer
  [   45.861035] ipr: Leaving ipr_reset_alert
  [   45.964302] ipr: Entering ipr_reset_start_bist
  [   45.964309] ipr: Entering ipr_reset_start_timer
  [   45.964313] ipr: Leaving ipr_reset_start_bist
  [   46.264301] ipr: Entering ipr_reset_bist_done
  [   46.264309] ipr: Leaving ipr_reset_bist_done

During adapter reset, ipr device driver blocks config space access but
can't block MMIO access for MSI-X entries.  There is very small window:
irqbalance daemon kicks in during adapter reset before ipr driver calls
pci_restore_state(pdev) to restore MSI-X table.

irqbalance daemon reads back all 0 for that MSI-X vector in
__pci_read_msi_msg().

irqbalance daemon:

  msi_domain_set_affinity()
  ->irq_chip_set_affinity_patent()
  ->xive_irq_set_affinity()
  ->irq_chip_compose_msi_msg()
    ->pseries_msi_compose_msg()
    ->__pci_read_msi_msg(): read all 0 since didn't call pci_restore_state
  ->irq_chip_write_msi_msg()
    -> pci_write_msg_msi(): write 0 to the msix vector entry

When ipr driver calls pci_restore_state(pdev) in
ipr_reset_restore_cfg_space(), the MSI-X vector entry has been cleared
by irqbalance daemon in pci_write_msg_msix().

  pci_restore_state()
  ->__pci_restore_msix_state()

Below is the MSI-X table for ipr adapter after irqbalance daemon kicked
in during adapter reset:

  Dump MSIx table: index=0 address_lo=c800 address_hi=10000000 msg_data=0
  Dump MSIx table: index=1 address_lo=c810 address_hi=10000000 msg_data=0
  Dump MSIx table: index=2 address_lo=c820 address_hi=10000000 msg_data=0
  Dump MSIx table: index=3 address_lo=c830 address_hi=10000000 msg_data=0
  Dump MSIx table: index=4 address_lo=c840 address_hi=10000000 msg_data=0
  Dump MSIx table: index=5 address_lo=c850 address_hi=10000000 msg_data=0
  Dump MSIx table: index=6 address_lo=c860 address_hi=10000000 msg_data=0
  Dump MSIx table: index=7 address_lo=c870 address_hi=10000000 msg_data=0
  Dump MSIx table: index=8 address_lo=0 address_hi=0 msg_data=0
  ---------> Hit EEH since msix vector of index=8 are 0
  Dump MSIx table: index=9 address_lo=c890 address_hi=10000000 msg_data=0
  Dump MSIx table: index=10 address_lo=c8a0 address_hi=10000000 msg_data=0
  Dump MSIx table: index=11 address_lo=c8b0 address_hi=10000000 msg_data=0
  Dump MSIx table: index=12 address_lo=c8c0 address_hi=10000000 msg_data=0
  Dump MSIx table: index=13 address_lo=c8d0 address_hi=10000000 msg_data=0
  Dump MSIx table: index=14 address_lo=c8e0 address_hi=10000000 msg_data=0
  Dump MSIx table: index=15 address_lo=c8f0 address_hi=10000000 msg_data=0

  [   46.264312] ipr: Entering ipr_reset_restore_cfg_space
  [   46.267439] ipr: Entering ipr_fail_all_ops
  [   46.267447] ipr: Leaving ipr_fail_all_ops
  [   46.267451] ipr: Leaving ipr_reset_restore_cfg_space
  [   46.267454] ipr: Entering ipr_ioa_bringdown_done
  [   46.267458] ipr: Leaving ipr_ioa_bringdown_done
  [   46.267467] ipr: Entering ipr_worker_thread
  [   46.267470] ipr: Leaving ipr_worker_thread

IRQ balancing is not required during adapter reset.

Enable "IRQ_NO_BALANCING" flag before starting adapter reset and disable
it after calling pci_restore_state(). The irqbalance daemon is disabled
for this short period of time (~2s).

Co-developed-by: Kyle Mahlkuch <Kyle.Mahlkuch@ibm.com>
Signed-off-by: Kyle Mahlkuch <Kyle.Mahlkuch@ibm.com>
Signed-off-by: Wen Xiong <wenxiong@linux.ibm.com>
Link: https://patch.msgid.link/20251028142427.3969819-2-wenxiong@linux.ibm.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-11-29 15:56:18 -05:00
Duoming Zhou
ab58153ec6 scsi: imm: Fix use-after-free bug caused by unfinished delayed work
The delayed work item 'imm_tq' is initialized in imm_attach() and
scheduled via imm_queuecommand() for processing SCSI commands.  When the
IMM parallel port SCSI host adapter is detached through imm_detach(),
the imm_struct device instance is deallocated.

However, the delayed work might still be pending or executing
when imm_detach() is called, leading to use-after-free bugs
when the work function imm_interrupt() accesses the already
freed imm_struct memory.

The race condition can occur as follows:

CPU 0(detach thread)   | CPU 1
                       | imm_queuecommand()
                       |   imm_queuecommand_lck()
imm_detach()           |     schedule_delayed_work()
  kfree(dev) //FREE    | imm_interrupt()
                       |   dev = container_of(...) //USE
                           dev-> //USE

Add disable_delayed_work_sync() in imm_detach() to guarantee proper
cancellation of the delayed work item before imm_struct is deallocated.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Link: https://patch.msgid.link/20251028100149.40721-1-duoming@zju.edu.cn
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-11-29 15:42:17 -05:00
Heiko Carstens
971bb08704 scsi: target: sbp: Remove KMSG_COMPONENT macro
The KMSG_COMPONENT macro is a leftover of the s390 specific "kernel
message catalog" from 2008 [1] which never made it upstream.

The macro was added to s390 code to allow for an out-of-tree patch which
used this to generate unique message ids. Also this out-of-tree doesn't
exist anymore.

The pattern of how the KMSG_COMPONENT is used was partially also used
for non s390 specific code, for whatever reasons.

Remove the macro in order to get rid of a pointless indirection.

[1] https://lwn.net/Articles/292650/

Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Link: https://patch.msgid.link/20251126144027.2213895-1-hca@linux.ibm.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-11-29 15:27:33 -05:00
Miao Li
c131c9bf98 scsi: core: Correct documentation for scsi_device_quiesce()
If scsi_device_quiesce() returns zero, the function executed successfully.

Signed-off-by: Miao Li <limiao@kylinos.cn>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Link: https://patch.msgid.link/20251124075444.32699-1-limiao870622@163.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-11-29 15:20:15 -05:00
Suganath Prabu S
4588e65cfd scsi: mpi3mr: Prevent duplicate SAS/SATA device entries in channel 1
Avoid scanning SAS/SATA devices in channel 1 when SAS transport is
enabled, as the SAS/SATA devices are exposed through channel 0.

Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com>
Link: https://lore.kernel.org/stable/20251120071955.463475-1-suganath-prabu.subramani%40broadcom.com
Link: https://patch.msgid.link/20251120071955.463475-1-suganath-prabu.subramani@broadcom.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-11-29 15:08:41 -05:00
Andrey Vatoropin
5053eab38a scsi: target: Reset t_task_cdb pointer in error case
If allocation of cmd->t_task_cdb fails, it remains NULL but is later
dereferenced in the 'err' path.

In case of error, reset NULL t_task_cdb value to point at the default
fixed-size buffer.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 9e95fb805dc0 ("scsi: target: Fix NULL pointer dereference")
Cc: stable@vger.kernel.org
Signed-off-by: Andrey Vatoropin <a.vatoropin@crpt.ru>
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Link: https://patch.msgid.link/20251118084014.324940-1-a.vatoropin@crpt.ru
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-11-29 15:06:12 -05:00
Brian Kao
b4bb6daf4a scsi: ufs: core: Fix EH failure after W-LUN resume error
When a W-LUN resume fails, its parent devices in the SCSI hierarchy,
including the scsi_target, may be runtime suspended. Subsequently, the
error handler in ufshcd_recover_pm_error() fails to set the W-LUN device
back to active because the parent target is not active.  This results in
the following errors:

  google-ufshcd 3c2d0000.ufs: ufshcd_err_handler started; HBA state eh_fatal; ...
  ufs_device_wlun 0:0:0:49488: START_STOP failed for power mode: 1, result 40000
  ufs_device_wlun 0:0:0:49488: ufshcd_wl_runtime_resume failed: -5
  ...
  ufs_device_wlun 0:0:0:49488: runtime PM trying to activate child device 0:0:0:49488 but parent (target0:0:0) is not active

Address this by:

 1. Ensuring the W-LUN's parent scsi_target is runtime resumed before
    attempting to set the W-LUN to active within
    ufshcd_recover_pm_error().

 2. Explicitly checking for power.runtime_error on the HBA and W-LUN
    devices before calling pm_runtime_set_active() to clear the error
    state.

 3. Adding pm_runtime_get_sync(hba->dev) in
    ufshcd_err_handling_prepare() to ensure the HBA itself is active
    during error recovery, even if a child device resume failed.

These changes ensure the device power states are managed correctly
during error recovery.

Signed-off-by: Brian Kao <powenkao@google.com>
Tested-by: Brian Kao <powenkao@google.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20251112063214.1195761-1-powenkao@google.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
2025-11-29 14:58:38 -05:00
29 changed files with 487 additions and 146 deletions

View File

@ -1,8 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 6
PATCHLEVEL = 18
PATCHLEVEL = 19
SUBLEVEL = 0
EXTRAVERSION =
EXTRAVERSION = -rc1
NAME = Baby Opossum Posse
# *DOCUMENTATION*

View File

@ -316,9 +316,6 @@ config BLK_DEV_RBD
tristate "Rados block device (RBD)"
depends on INET && BLOCK
select CEPH_LIB
select CRC32
select CRYPTO_AES
select CRYPTO
help
Say Y here if you want include the Rados block device, which stripes
a block device over objects stored in the Ceph distributed object

View File

@ -950,6 +950,19 @@ static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps
q = bdev_get_queue(p->path.dev->bdev);
attached_handler_name = scsi_dh_attached_handler_name(q, GFP_KERNEL);
if (IS_ERR(attached_handler_name)) {
if (PTR_ERR(attached_handler_name) == -ENODEV) {
if (m->hw_handler_name) {
DMERR("hardware handlers are only allowed for SCSI devices");
kfree(m->hw_handler_name);
m->hw_handler_name = NULL;
}
attached_handler_name = NULL;
} else {
r = PTR_ERR(attached_handler_name);
goto bad;
}
}
if (attached_handler_name || m->hw_handler_name) {
INIT_DELAYED_WORK(&p->activate_path, activate_path_work);
r = setup_scsi_dh(p->path.dev->bdev, m, &attached_handler_name, &ti->error);

View File

@ -106,7 +106,6 @@ config PHANTOM
config RPMB
tristate "RPMB partition interface"
depends on MMC || SCSI_UFSHCD
help
Unified RPMB unit interface for RPMB capable devices such as eMMC and
UFS. Provides interface for in-kernel security controllers to access

View File

@ -1260,6 +1260,7 @@ static void imm_detach(struct parport *pb)
imm_struct *dev;
list_for_each_entry(dev, &imm_hosts, list) {
if (dev->dev->port == pb) {
disable_delayed_work_sync(&dev->imm_tq);
list_del_init(&dev->list);
scsi_remove_host(dev->host);
scsi_host_put(dev->host);

View File

@ -61,8 +61,8 @@
#include <linux/hdreg.h>
#include <linux/reboot.h>
#include <linux/stringify.h>
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/processor.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
@ -7843,6 +7843,30 @@ static int ipr_dump_mailbox_wait(struct ipr_cmnd *ipr_cmd)
return IPR_RC_JOB_RETURN;
}
/**
* ipr_set_affinity_nobalance
* @ioa_cfg: ipr_ioa_cfg struct for an ipr device
* @flag: bool
* true: ensable "IRQ_NO_BALANCING" bit for msix interrupt
* false: disable "IRQ_NO_BALANCING" bit for msix interrupt
* Description: This function will be called to disable/enable
* "IRQ_NO_BALANCING" to avoid irqbalance daemon
* kicking in during adapter reset.
**/
static void ipr_set_affinity_nobalance(struct ipr_ioa_cfg *ioa_cfg, bool flag)
{
int irq, i;
for (i = 0; i < ioa_cfg->nvectors; i++) {
irq = pci_irq_vector(ioa_cfg->pdev, i);
if (flag)
irq_set_status_flags(irq, IRQ_NO_BALANCING);
else
irq_clear_status_flags(irq, IRQ_NO_BALANCING);
}
}
/**
* ipr_reset_restore_cfg_space - Restore PCI config space.
* @ipr_cmd: ipr command struct
@ -7866,6 +7890,7 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
return IPR_RC_JOB_CONTINUE;
}
ipr_set_affinity_nobalance(ioa_cfg, false);
ipr_fail_all_ops(ioa_cfg);
if (ioa_cfg->sis64) {
@ -7945,6 +7970,7 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd)
rc = pci_write_config_byte(ioa_cfg->pdev, PCI_BIST, PCI_BIST_START);
if (rc == PCIBIOS_SUCCESSFUL) {
ipr_set_affinity_nobalance(ioa_cfg, true);
ipr_cmd->job_step = ipr_reset_bist_done;
ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT);
rc = IPR_RC_JOB_RETURN;

View File

@ -141,6 +141,7 @@ Undo_event_q:
Undo_ports:
sas_unregister_ports(sas_ha);
Undo_phys:
sas_unregister_phys(sas_ha);
return error;
}

View File

@ -54,6 +54,7 @@ void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev);
void sas_scsi_recover_host(struct Scsi_Host *shost);
int sas_register_phys(struct sas_ha_struct *sas_ha);
void sas_unregister_phys(struct sas_ha_struct *sas_ha);
struct asd_sas_event *sas_alloc_event(struct asd_sas_phy *phy, gfp_t gfp_flags);
void sas_free_event(struct asd_sas_event *event);
@ -145,20 +146,6 @@ static inline void sas_fail_probe(struct domain_device *dev, const char *func, i
func, dev->parent ? "exp-attached" :
"direct-attached",
SAS_ADDR(dev->sas_addr), err);
/*
* If the device probe failed, the expander phy attached address
* needs to be reset so that the phy will not be treated as flutter
* in the next revalidation
*/
if (dev->parent && !dev_is_expander(dev->dev_type)) {
struct sas_phy *phy = dev->phy;
struct domain_device *parent = dev->parent;
struct ex_phy *ex_phy = &parent->ex_dev.ex_phy[phy->number];
memset(ex_phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
}
sas_unregister_dev(dev->port, dev);
}

View File

@ -116,6 +116,7 @@ static void sas_phye_shutdown(struct work_struct *work)
int sas_register_phys(struct sas_ha_struct *sas_ha)
{
int i;
int err;
/* Now register the phys. */
for (i = 0; i < sas_ha->num_phys; i++) {
@ -132,8 +133,10 @@ int sas_register_phys(struct sas_ha_struct *sas_ha)
phy->frame_rcvd_size = 0;
phy->phy = sas_phy_alloc(&sas_ha->shost->shost_gendev, i);
if (!phy->phy)
return -ENOMEM;
if (!phy->phy) {
err = -ENOMEM;
goto rollback;
}
phy->phy->identify.initiator_port_protocols =
phy->iproto;
@ -146,10 +149,34 @@ int sas_register_phys(struct sas_ha_struct *sas_ha)
phy->phy->maximum_linkrate = SAS_LINK_RATE_UNKNOWN;
phy->phy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
sas_phy_add(phy->phy);
err = sas_phy_add(phy->phy);
if (err) {
sas_phy_free(phy->phy);
goto rollback;
}
}
return 0;
rollback:
for (i-- ; i >= 0 ; i--) {
struct asd_sas_phy *phy = sas_ha->sas_phy[i];
sas_phy_delete(phy->phy);
sas_phy_free(phy->phy);
}
return err;
}
void sas_unregister_phys(struct sas_ha_struct *sas_ha)
{
int i;
for (i = 0 ; i < sas_ha->num_phys ; i++) {
struct asd_sas_phy *phy = sas_ha->sas_phy[i];
sas_phy_delete(phy->phy);
sas_phy_free(phy->phy);
}
}
const work_func_t sas_phy_event_fns[PHY_NUM_EVENTS] = {

View File

@ -56,8 +56,8 @@ extern struct list_head mrioc_list;
extern int prot_mask;
extern atomic64_t event_counter;
#define MPI3MR_DRIVER_VERSION "8.15.0.5.50"
#define MPI3MR_DRIVER_RELDATE "12-August-2025"
#define MPI3MR_DRIVER_VERSION "8.15.0.5.51"
#define MPI3MR_DRIVER_RELDATE "18-November-2025"
#define MPI3MR_DRIVER_NAME "mpi3mr"
#define MPI3MR_DRIVER_LICENSE "GPL"

View File

@ -1184,6 +1184,8 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
if (is_added == true)
tgtdev->io_throttle_enabled =
(flags & MPI3_DEVICE0_FLAGS_IO_THROTTLING_REQUIRED) ? 1 : 0;
if (!mrioc->sas_transport_enabled)
tgtdev->non_stl = 1;
switch (flags & MPI3_DEVICE0_FLAGS_MAX_WRITE_SAME_MASK) {
case MPI3_DEVICE0_FLAGS_MAX_WRITE_SAME_256_LB:
@ -4844,7 +4846,7 @@ static int mpi3mr_target_alloc(struct scsi_target *starget)
spin_lock_irqsave(&mrioc->tgtdev_lock, flags);
if (starget->channel == mrioc->scsi_device_channel) {
tgt_dev = __mpi3mr_get_tgtdev_by_perst_id(mrioc, starget->id);
if (tgt_dev && !tgt_dev->is_hidden) {
if (tgt_dev && !tgt_dev->is_hidden && tgt_dev->non_stl) {
scsi_tgt_priv_data->starget = starget;
scsi_tgt_priv_data->dev_handle = tgt_dev->dev_handle;
scsi_tgt_priv_data->perst_id = tgt_dev->perst_id;

View File

@ -17,6 +17,7 @@
#include <linux/crash_dump.h>
#include <linux/trace_events.h>
#include <linux/trace.h>
#include <linux/irq.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsicam.h>
@ -7776,6 +7777,31 @@ static void qla_pci_error_cleanup(scsi_qla_host_t *vha)
}
/**
* qla2xxx_set_affinity_nobalance
* @pdev: pci_dev struct for a qla2xxx device
* @flag: bool
* true: enable "IRQ_NO_BALANCING" bit for msix interrupt
* false: disable "IRQ_NO_BALANCING" bit for msix interrupt
* Description: This function will be called to disable/enable
* "IRQ_NO_BALANCING" to avoid irqbalance daemon
* kicking in during adapter reset.
**/
static void qla2xxx_set_affinity_nobalance(struct pci_dev *pdev, bool flag)
{
int irq, i;
for (i = 0; i < QLA_BASE_VECTORS; i++) {
irq = pci_irq_vector(pdev, i);
if (flag)
irq_set_status_flags(irq, IRQ_NO_BALANCING);
else
irq_clear_status_flags(irq, IRQ_NO_BALANCING);
}
}
static pci_ers_result_t
qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
{
@ -7794,6 +7820,8 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
goto out;
}
qla2xxx_set_affinity_nobalance(pdev, false);
switch (state) {
case pci_channel_io_normal:
qla_pci_set_eeh_busy(vha);
@ -7930,6 +7958,8 @@ exit_slot_reset:
ql_dbg(ql_dbg_aer, base_vha, 0x900e,
"Slot Reset returning %x.\n", ret);
qla2xxx_set_affinity_nobalance(pdev, true);
return ret;
}

View File

@ -1552,7 +1552,7 @@ static int qla4_82xx_cmdpeg_ready(struct scsi_qla_host *ha, int pegtune_val)
(val == PHAN_INITIALIZE_ACK))
return 0;
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(500);
schedule_timeout(msecs_to_jiffies(500));
} while (--retries);

View File

@ -353,7 +353,8 @@ EXPORT_SYMBOL_GPL(scsi_dh_attach);
* that may have a device handler attached
* @gfp - the GFP mask used in the kmalloc() call when allocating memory
*
* Returns name of attached handler, NULL if no handler is attached.
* Returns name of attached handler, NULL if no handler is attached, or
* and error pointer if an error occurred.
* Caller must take care to free the returned string.
*/
const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp)
@ -363,10 +364,11 @@ const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp)
sdev = scsi_device_from_queue(q);
if (!sdev)
return NULL;
return ERR_PTR(-ENODEV);
if (sdev->handler)
handler_name = kstrdup(sdev->handler->name, gfp);
handler_name = kstrdup(sdev->handler->name, gfp) ? :
ERR_PTR(-ENOMEM);
put_device(&sdev->sdev_gendev);
return handler_name;
}

View File

@ -2801,7 +2801,7 @@ EXPORT_SYMBOL_GPL(sdev_evt_send_simple);
*
* Must be called with user context, may sleep.
*
* Returns zero if unsuccessful or an error if not.
* Returns zero if successful or an error if not.
*/
int
scsi_device_quiesce(struct scsi_device *sdev)

View File

@ -5,8 +5,7 @@
* Copyright (C) 2011 Chris Boot <bootc@bootc.net>
*/
#define KMSG_COMPONENT "sbp_target"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "sbp_target: " fmt
#include <linux/kernel.h>
#include <linux/module.h>

View File

@ -1524,6 +1524,7 @@ target_cmd_init_cdb(struct se_cmd *cmd, unsigned char *cdb, gfp_t gfp)
if (scsi_command_size(cdb) > sizeof(cmd->__t_task_cdb)) {
cmd->t_task_cdb = kzalloc(scsi_command_size(cdb), gfp);
if (!cmd->t_task_cdb) {
cmd->t_task_cdb = &cmd->__t_task_cdb[0];
pr_err("Unable to allocate cmd->t_task_cdb"
" %u > sizeof(cmd->__t_task_cdb): %lu ops\n",
scsi_command_size(cdb),

View File

@ -6,6 +6,7 @@
menuconfig SCSI_UFSHCD
tristate "Universal Flash Storage Controller"
depends on SCSI && SCSI_DMA
depends on RPMB || !RPMB
select PM_DEVFREQ
select DEVFREQ_GOV_SIMPLE_ONDEMAND
select NLS

View File

@ -1455,15 +1455,14 @@ out:
static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba, int err)
{
up_write(&hba->clk_scaling_lock);
mutex_unlock(&hba->wb_mutex);
blk_mq_unquiesce_tagset(&hba->host->tag_set);
mutex_unlock(&hba->host->scan_mutex);
/* Enable Write Booster if current gear requires it else disable it */
if (ufshcd_enable_wb_if_scaling_up(hba) && !err)
ufshcd_wb_toggle(hba, hba->pwr_info.gear_rx >= hba->clk_scaling.wb_gear);
mutex_unlock(&hba->wb_mutex);
blk_mq_unquiesce_tagset(&hba->host->tag_set);
mutex_unlock(&hba->host->scan_mutex);
ufshcd_release(hba);
}
@ -6504,6 +6503,11 @@ static void ufshcd_clk_scaling_suspend(struct ufs_hba *hba, bool suspend)
static void ufshcd_err_handling_prepare(struct ufs_hba *hba)
{
/*
* A WLUN resume failure could potentially lead to the HBA being
* runtime suspended, so take an extra reference on hba->dev.
*/
pm_runtime_get_sync(hba->dev);
ufshcd_rpm_get_sync(hba);
if (pm_runtime_status_suspended(&hba->ufs_device_wlun->sdev_gendev) ||
hba->is_sys_suspended) {
@ -6543,6 +6547,7 @@ static void ufshcd_err_handling_unprepare(struct ufs_hba *hba)
if (ufshcd_is_clkscaling_supported(hba))
ufshcd_clk_scaling_suspend(hba, false);
ufshcd_rpm_put(hba);
pm_runtime_put(hba->dev);
}
static inline bool ufshcd_err_handling_should_stop(struct ufs_hba *hba)
@ -6557,28 +6562,42 @@ static inline bool ufshcd_err_handling_should_stop(struct ufs_hba *hba)
#ifdef CONFIG_PM
static void ufshcd_recover_pm_error(struct ufs_hba *hba)
{
struct scsi_target *starget = hba->ufs_device_wlun->sdev_target;
struct Scsi_Host *shost = hba->host;
struct scsi_device *sdev;
struct request_queue *q;
int ret;
bool resume_sdev_queues = false;
hba->is_sys_suspended = false;
/*
* Set RPM status of wlun device to RPM_ACTIVE,
* this also clears its runtime error.
*/
ret = pm_runtime_set_active(&hba->ufs_device_wlun->sdev_gendev);
/* hba device might have a runtime error otherwise */
if (ret)
ret = pm_runtime_set_active(hba->dev);
/*
* Ensure the parent's error status is cleared before proceeding
* to the child, as the parent must be active to activate the child.
*/
if (hba->dev->power.runtime_error) {
/* hba->dev has no functional parent thus simplily set RPM_ACTIVE */
pm_runtime_set_active(hba->dev);
resume_sdev_queues = true;
}
if (hba->ufs_device_wlun->sdev_gendev.power.runtime_error) {
/*
* starget, parent of wlun, might be suspended if wlun resume failed.
* Make sure parent is resumed before set child (wlun) active.
*/
pm_runtime_get_sync(&starget->dev);
pm_runtime_set_active(&hba->ufs_device_wlun->sdev_gendev);
pm_runtime_put_sync(&starget->dev);
resume_sdev_queues = true;
}
/*
* If wlun device had runtime error, we also need to resume those
* consumer scsi devices in case any of them has failed to be
* resumed due to supplier runtime resume failure. This is to unblock
* blk_queue_enter in case there are bios waiting inside it.
*/
if (!ret) {
if (resume_sdev_queues) {
shost_for_each_device(sdev, shost) {
q = sdev->request_queue;
if (q->dev && (q->rpm_status == RPM_SUSPENDED ||
@ -6679,19 +6698,22 @@ static void ufshcd_err_handler(struct work_struct *work)
hba->saved_uic_err, hba->force_reset,
ufshcd_is_link_broken(hba) ? "; link is broken" : "");
/*
* Use ufshcd_rpm_get_noresume() here to safely perform link recovery
* even if an error occurs during runtime suspend or runtime resume.
* This avoids potential deadlocks that could happen if we tried to
* resume the device while a PM operation is already in progress.
*/
ufshcd_rpm_get_noresume(hba);
if (hba->pm_op_in_progress) {
ufshcd_link_recovery(hba);
if (hba->ufs_device_wlun) {
/*
* Use ufshcd_rpm_get_noresume() here to safely perform link
* recovery even if an error occurs during runtime suspend or
* runtime resume. This avoids potential deadlocks that could
* happen if we tried to resume the device while a PM operation
* is already in progress.
*/
ufshcd_rpm_get_noresume(hba);
if (hba->pm_op_in_progress) {
ufshcd_link_recovery(hba);
ufshcd_rpm_put(hba);
return;
}
ufshcd_rpm_put(hba);
return;
}
ufshcd_rpm_put(hba);
down(&hba->host_sem);
spin_lock_irqsave(hba->host->host_lock, flags);

View File

@ -1769,10 +1769,9 @@ static void ufs_qcom_dump_testbus(struct ufs_hba *hba)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
int i, j, nminor = 0, testbus_len = 0;
u32 *testbus __free(kfree) = NULL;
char *prefix;
testbus = kmalloc_array(256, sizeof(u32), GFP_KERNEL);
u32 *testbus __free(kfree) = kmalloc_array(256, sizeof(u32), GFP_KERNEL);
if (!testbus)
return;
@ -1794,13 +1793,12 @@ static void ufs_qcom_dump_testbus(struct ufs_hba *hba)
static int ufs_qcom_dump_regs(struct ufs_hba *hba, size_t offset, size_t len,
const char *prefix, void __iomem *base)
{
u32 *regs __free(kfree) = NULL;
size_t pos;
if (offset % 4 != 0 || len % 4 != 0)
return -EINVAL;
regs = kzalloc(len, GFP_ATOMIC);
u32 *regs __free(kfree) = kzalloc(len, GFP_ATOMIC);
if (!regs)
return -ENOMEM;

View File

@ -3,9 +3,6 @@ config CEPH_FS
tristate "Ceph distributed file system"
depends on INET
select CEPH_LIB
select CRC32
select CRYPTO_AES
select CRYPTO
select NETFS_SUPPORT
select FS_ENCRYPTION_ALGS if FS_ENCRYPTION
default n

View File

@ -18,6 +18,7 @@
#include "crypto.h"
#include <linux/ceph/decode.h>
#include <linux/ceph/messenger.h>
#include <trace/events/ceph.h>
/*
* Capability management
@ -4452,6 +4453,9 @@ void ceph_handle_caps(struct ceph_mds_session *session,
session->s_mds, ceph_cap_op_name(op), vino.ino, vino.snap, inode,
seq, issue_seq, mseq);
trace_ceph_handle_caps(mdsc, session, op, &vino, ceph_inode(inode),
seq, issue_seq, mseq);
mutex_lock(&session->s_mutex);
if (!inode) {

View File

@ -24,6 +24,7 @@
#include <linux/ceph/pagelist.h>
#include <linux/ceph/auth.h>
#include <linux/ceph/debugfs.h>
#include <trace/events/ceph.h>
#define RECONNECT_MAX_SIZE (INT_MAX - PAGE_SIZE)
@ -3288,6 +3289,8 @@ static void complete_request(struct ceph_mds_client *mdsc,
{
req->r_end_latency = ktime_get();
trace_ceph_mdsc_complete_request(mdsc, req);
if (req->r_callback)
req->r_callback(mdsc, req);
complete_all(&req->r_completion);
@ -3419,6 +3422,8 @@ static int __send_request(struct ceph_mds_session *session,
{
int err;
trace_ceph_mdsc_send_request(session, req);
err = __prepare_send_request(session, req, drop_cap_releases);
if (!err) {
ceph_msg_get(req->r_request);
@ -3470,6 +3475,8 @@ static void __do_request(struct ceph_mds_client *mdsc,
}
if (mdsc->mdsmap->m_epoch == 0) {
doutc(cl, "no mdsmap, waiting for map\n");
trace_ceph_mdsc_suspend_request(mdsc, session, req,
ceph_mdsc_suspend_reason_no_mdsmap);
list_add(&req->r_wait, &mdsc->waiting_for_map);
return;
}
@ -3491,6 +3498,8 @@ static void __do_request(struct ceph_mds_client *mdsc,
goto finish;
}
doutc(cl, "no mds or not active, waiting for map\n");
trace_ceph_mdsc_suspend_request(mdsc, session, req,
ceph_mdsc_suspend_reason_no_active_mds);
list_add(&req->r_wait, &mdsc->waiting_for_map);
return;
}
@ -3536,9 +3545,11 @@ static void __do_request(struct ceph_mds_client *mdsc,
* it to the mdsc queue.
*/
if (session->s_state == CEPH_MDS_SESSION_REJECTED) {
if (ceph_test_mount_opt(mdsc->fsc, CLEANRECOVER))
if (ceph_test_mount_opt(mdsc->fsc, CLEANRECOVER)) {
trace_ceph_mdsc_suspend_request(mdsc, session, req,
ceph_mdsc_suspend_reason_rejected);
list_add(&req->r_wait, &mdsc->waiting_for_map);
else
} else
err = -EACCES;
goto out_session;
}
@ -3552,6 +3563,8 @@ static void __do_request(struct ceph_mds_client *mdsc,
if (random)
req->r_resend_mds = mds;
}
trace_ceph_mdsc_suspend_request(mdsc, session, req,
ceph_mdsc_suspend_reason_session);
list_add(&req->r_wait, &session->s_waiting);
goto out_session;
}
@ -3652,6 +3665,7 @@ static void __wake_requests(struct ceph_mds_client *mdsc,
list_del_init(&req->r_wait);
doutc(cl, " wake request %p tid %llu\n", req,
req->r_tid);
trace_ceph_mdsc_resume_request(mdsc, req);
__do_request(mdsc, req);
}
}
@ -3678,6 +3692,7 @@ static void kick_requests(struct ceph_mds_client *mdsc, int mds)
req->r_session->s_mds == mds) {
doutc(cl, " kicking tid %llu\n", req->r_tid);
list_del_init(&req->r_wait);
trace_ceph_mdsc_resume_request(mdsc, req);
__do_request(mdsc, req);
}
}
@ -3724,6 +3739,7 @@ int ceph_mdsc_submit_request(struct ceph_mds_client *mdsc, struct inode *dir,
doutc(cl, "submit_request on %p for inode %p\n", req, dir);
mutex_lock(&mdsc->mutex);
__register_request(mdsc, req, dir);
trace_ceph_mdsc_submit_request(mdsc, req);
__do_request(mdsc, req);
err = req->r_err;
mutex_unlock(&mdsc->mutex);

View File

@ -374,7 +374,7 @@ static int build_snap_context(struct ceph_mds_client *mdsc,
/* alloc new snap context */
err = -ENOMEM;
if (num > (SIZE_MAX - sizeof(*snapc)) / sizeof(u64))
if ((size_t)num > (SIZE_MAX - sizeof(*snapc)) / sizeof(u64))
goto fail;
snapc = ceph_create_snap_context(num, GFP_NOFS);
if (!snapc)

View File

@ -30,6 +30,9 @@
#include <uapi/linux/magic.h>
#define CREATE_TRACE_POINTS
#include <trace/events/ceph.h>
static DEFINE_SPINLOCK(ceph_fsc_lock);
static LIST_HEAD(ceph_fsc_list);

234
include/trace/events/ceph.h Normal file
View File

@ -0,0 +1,234 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Ceph filesystem support module tracepoints
*
* Copyright (C) 2025 IONOS SE. All Rights Reserved.
* Written by Max Kellermann (max.kellermann@ionos.com)
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM ceph
#if !defined(_TRACE_CEPH_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_CEPH_H
#include <linux/tracepoint.h>
#define ceph_mdsc_suspend_reasons \
EM(ceph_mdsc_suspend_reason_no_mdsmap, "no-mdsmap") \
EM(ceph_mdsc_suspend_reason_no_active_mds, "no-active-mds") \
EM(ceph_mdsc_suspend_reason_rejected, "rejected") \
E_(ceph_mdsc_suspend_reason_session, "session")
#ifndef __NETFS_DECLARE_TRACE_ENUMS_ONCE_ONLY
#define __NETFS_DECLARE_TRACE_ENUMS_ONCE_ONLY
#undef EM
#undef E_
#define EM(a, b) a,
#define E_(a, b) a
enum ceph_mdsc_suspend_reason { ceph_mdsc_suspend_reasons } __mode(byte);
#endif
/*
* Export enum symbols via userspace.
*/
#undef EM
#undef E_
#define EM(a, b) TRACE_DEFINE_ENUM(a);
#define E_(a, b) TRACE_DEFINE_ENUM(a);
ceph_mdsc_suspend_reasons;
/*
* Now redefine the EM() and E_() macros to map the enums to the strings that
* will be printed in the output.
*/
#undef EM
#undef E_
#define EM(a, b) { a, b },
#define E_(a, b) { a, b }
TRACE_EVENT(ceph_mdsc_submit_request,
TP_PROTO(struct ceph_mds_client *mdsc,
struct ceph_mds_request *req),
TP_ARGS(mdsc, req),
TP_STRUCT__entry(
__field(u64, tid)
__field(int, op)
__field(u64, ino)
__field(u64, snap)
),
TP_fast_assign(
struct inode *inode;
__entry->tid = req->r_tid;
__entry->op = req->r_op;
inode = req->r_inode;
if (inode == NULL && req->r_dentry)
inode = d_inode(req->r_dentry);
if (inode) {
__entry->ino = ceph_ino(inode);
__entry->snap = ceph_snap(inode);
} else {
__entry->ino = __entry->snap = 0;
}
),
TP_printk("R=%llu op=%s ino=%llx,%llx",
__entry->tid,
ceph_mds_op_name(__entry->op),
__entry->ino, __entry->snap)
);
TRACE_EVENT(ceph_mdsc_suspend_request,
TP_PROTO(struct ceph_mds_client *mdsc,
struct ceph_mds_session *session,
struct ceph_mds_request *req,
enum ceph_mdsc_suspend_reason reason),
TP_ARGS(mdsc, session, req, reason),
TP_STRUCT__entry(
__field(u64, tid)
__field(int, op)
__field(int, mds)
__field(enum ceph_mdsc_suspend_reason, reason)
),
TP_fast_assign(
__entry->tid = req->r_tid;
__entry->op = req->r_op;
__entry->mds = session ? session->s_mds : -1;
__entry->reason = reason;
),
TP_printk("R=%llu op=%s reason=%s",
__entry->tid,
ceph_mds_op_name(__entry->op),
__print_symbolic(__entry->reason, ceph_mdsc_suspend_reasons))
);
TRACE_EVENT(ceph_mdsc_resume_request,
TP_PROTO(struct ceph_mds_client *mdsc,
struct ceph_mds_request *req),
TP_ARGS(mdsc, req),
TP_STRUCT__entry(
__field(u64, tid)
__field(int, op)
),
TP_fast_assign(
__entry->tid = req->r_tid;
__entry->op = req->r_op;
),
TP_printk("R=%llu op=%s",
__entry->tid,
ceph_mds_op_name(__entry->op))
);
TRACE_EVENT(ceph_mdsc_send_request,
TP_PROTO(struct ceph_mds_session *session,
struct ceph_mds_request *req),
TP_ARGS(session, req),
TP_STRUCT__entry(
__field(u64, tid)
__field(int, op)
__field(int, mds)
),
TP_fast_assign(
__entry->tid = req->r_tid;
__entry->op = req->r_op;
__entry->mds = session->s_mds;
),
TP_printk("R=%llu op=%s mds=%d",
__entry->tid,
ceph_mds_op_name(__entry->op),
__entry->mds)
);
TRACE_EVENT(ceph_mdsc_complete_request,
TP_PROTO(struct ceph_mds_client *mdsc,
struct ceph_mds_request *req),
TP_ARGS(mdsc, req),
TP_STRUCT__entry(
__field(u64, tid)
__field(int, op)
__field(int, err)
__field(unsigned long, latency_ns)
),
TP_fast_assign(
__entry->tid = req->r_tid;
__entry->op = req->r_op;
__entry->err = req->r_err;
__entry->latency_ns = req->r_end_latency - req->r_start_latency;
),
TP_printk("R=%llu op=%s err=%d latency_ns=%lu",
__entry->tid,
ceph_mds_op_name(__entry->op),
__entry->err,
__entry->latency_ns)
);
TRACE_EVENT(ceph_handle_caps,
TP_PROTO(struct ceph_mds_client *mdsc,
struct ceph_mds_session *session,
int op,
const struct ceph_vino *vino,
struct ceph_inode_info *inode,
u32 seq, u32 mseq, u32 issue_seq),
TP_ARGS(mdsc, session, op, vino, inode, seq, mseq, issue_seq),
TP_STRUCT__entry(
__field(int, mds)
__field(int, op)
__field(u64, ino)
__field(u64, snap)
__field(u32, seq)
__field(u32, mseq)
__field(u32, issue_seq)
),
TP_fast_assign(
__entry->mds = session->s_mds;
__entry->op = op;
__entry->ino = vino->ino;
__entry->snap = vino->snap;
__entry->seq = seq;
__entry->mseq = mseq;
__entry->issue_seq = issue_seq;
),
TP_printk("mds=%d op=%s vino=%llx.%llx seq=%u iseq=%u mseq=%u",
__entry->mds,
ceph_cap_op_name(__entry->op),
__entry->ino,
__entry->snap,
__entry->seq,
__entry->issue_seq,
__entry->mseq)
);
#undef EM
#undef E_
#endif /* _TRACE_CEPH_H */
/* This part must be outside protection */
#include <trace/define_trace.h>

View File

@ -1280,8 +1280,7 @@ static struct ceph_osd *create_osd(struct ceph_osd_client *osdc, int onum)
static struct ceph_osd *get_osd(struct ceph_osd *osd)
{
if (refcount_inc_not_zero(&osd->o_ref)) {
dout("get_osd %p %d -> %d\n", osd, refcount_read(&osd->o_ref)-1,
refcount_read(&osd->o_ref));
dout("get_osd %p -> %d\n", osd, refcount_read(&osd->o_ref));
return osd;
} else {
dout("get_osd %p FAIL\n", osd);
@ -1291,8 +1290,7 @@ static struct ceph_osd *get_osd(struct ceph_osd *osd)
static void put_osd(struct ceph_osd *osd)
{
dout("put_osd %p %d -> %d\n", osd, refcount_read(&osd->o_ref),
refcount_read(&osd->o_ref) - 1);
dout("put_osd %p -> %d\n", osd, refcount_read(&osd->o_ref) - 1);
if (refcount_dec_and_test(&osd->o_ref)) {
osd_cleanup(osd);
kfree(osd);

View File

@ -806,51 +806,49 @@ static int decode_pool(void **p, void *end, struct ceph_pg_pool_info *pi)
ceph_decode_need(p, end, len, bad);
pool_end = *p + len;
ceph_decode_need(p, end, 4 + 4 + 4, bad);
pi->type = ceph_decode_8(p);
pi->size = ceph_decode_8(p);
pi->crush_ruleset = ceph_decode_8(p);
pi->object_hash = ceph_decode_8(p);
pi->pg_num = ceph_decode_32(p);
pi->pgp_num = ceph_decode_32(p);
*p += 4 + 4; /* skip lpg* */
*p += 4; /* skip last_change */
*p += 8 + 4; /* skip snap_seq, snap_epoch */
/* lpg*, last_change, snap_seq, snap_epoch */
ceph_decode_skip_n(p, end, 8 + 4 + 8 + 4, bad);
/* skip snaps */
num = ceph_decode_32(p);
ceph_decode_32_safe(p, end, num, bad);
while (num--) {
*p += 8; /* snapid key */
*p += 1 + 1; /* versions */
len = ceph_decode_32(p);
*p += len;
/* snapid key, pool snap (with versions) */
ceph_decode_skip_n(p, end, 8 + 2, bad);
ceph_decode_skip_string(p, end, bad);
}
/* skip removed_snaps */
num = ceph_decode_32(p);
*p += num * (8 + 8);
/* removed_snaps */
ceph_decode_skip_map(p, end, 64, 64, bad);
ceph_decode_need(p, end, 8 + 8 + 4, bad);
*p += 8; /* skip auid */
pi->flags = ceph_decode_64(p);
*p += 4; /* skip crash_replay_interval */
if (ev >= 7)
pi->min_size = ceph_decode_8(p);
ceph_decode_8_safe(p, end, pi->min_size, bad);
else
pi->min_size = pi->size - pi->size / 2;
if (ev >= 8)
*p += 8 + 8; /* skip quota_max_* */
/* quota_max_* */
ceph_decode_skip_n(p, end, 8 + 8, bad);
if (ev >= 9) {
/* skip tiers */
num = ceph_decode_32(p);
*p += num * 8;
/* tiers */
ceph_decode_skip_set(p, end, 64, bad);
ceph_decode_need(p, end, 8 + 1 + 8 + 8, bad);
*p += 8; /* skip tier_of */
*p += 1; /* skip cache_mode */
pi->read_tier = ceph_decode_64(p);
pi->write_tier = ceph_decode_64(p);
} else {
@ -858,86 +856,76 @@ static int decode_pool(void **p, void *end, struct ceph_pg_pool_info *pi)
pi->write_tier = -1;
}
if (ev >= 10) {
/* skip properties */
num = ceph_decode_32(p);
while (num--) {
len = ceph_decode_32(p);
*p += len; /* key */
len = ceph_decode_32(p);
*p += len; /* val */
}
}
if (ev >= 10)
/* properties */
ceph_decode_skip_map(p, end, string, string, bad);
if (ev >= 11) {
/* skip hit_set_params */
*p += 1 + 1; /* versions */
len = ceph_decode_32(p);
*p += len;
/* hit_set_params (with versions) */
ceph_decode_skip_n(p, end, 2, bad);
ceph_decode_skip_string(p, end, bad);
*p += 4; /* skip hit_set_period */
*p += 4; /* skip hit_set_count */
/* hit_set_period, hit_set_count */
ceph_decode_skip_n(p, end, 4 + 4, bad);
}
if (ev >= 12)
*p += 4; /* skip stripe_width */
/* stripe_width */
ceph_decode_skip_32(p, end, bad);
if (ev >= 13) {
*p += 8; /* skip target_max_bytes */
*p += 8; /* skip target_max_objects */
*p += 4; /* skip cache_target_dirty_ratio_micro */
*p += 4; /* skip cache_target_full_ratio_micro */
*p += 4; /* skip cache_min_flush_age */
*p += 4; /* skip cache_min_evict_age */
}
if (ev >= 13)
/* target_max_*, cache_target_*, cache_min_* */
ceph_decode_skip_n(p, end, 16 + 8 + 8, bad);
if (ev >= 14) {
/* skip erasure_code_profile */
len = ceph_decode_32(p);
*p += len;
}
if (ev >= 14)
/* erasure_code_profile */
ceph_decode_skip_string(p, end, bad);
/*
* last_force_op_resend_preluminous, will be overridden if the
* map was encoded with RESEND_ON_SPLIT
*/
if (ev >= 15)
pi->last_force_request_resend = ceph_decode_32(p);
ceph_decode_32_safe(p, end, pi->last_force_request_resend, bad);
else
pi->last_force_request_resend = 0;
if (ev >= 16)
*p += 4; /* skip min_read_recency_for_promote */
/* min_read_recency_for_promote */
ceph_decode_skip_32(p, end, bad);
if (ev >= 17)
*p += 8; /* skip expected_num_objects */
/* expected_num_objects */
ceph_decode_skip_64(p, end, bad);
if (ev >= 19)
*p += 4; /* skip cache_target_dirty_high_ratio_micro */
/* cache_target_dirty_high_ratio_micro */
ceph_decode_skip_32(p, end, bad);
if (ev >= 20)
*p += 4; /* skip min_write_recency_for_promote */
/* min_write_recency_for_promote */
ceph_decode_skip_32(p, end, bad);
if (ev >= 21)
*p += 1; /* skip use_gmt_hitset */
/* use_gmt_hitset */
ceph_decode_skip_8(p, end, bad);
if (ev >= 22)
*p += 1; /* skip fast_read */
/* fast_read */
ceph_decode_skip_8(p, end, bad);
if (ev >= 23) {
*p += 4; /* skip hit_set_grade_decay_rate */
*p += 4; /* skip hit_set_search_last_n */
}
if (ev >= 23)
/* hit_set_grade_decay_rate, hit_set_search_last_n */
ceph_decode_skip_n(p, end, 4 + 4, bad);
if (ev >= 24) {
/* skip opts */
*p += 1 + 1; /* versions */
len = ceph_decode_32(p);
*p += len;
/* opts (with versions) */
ceph_decode_skip_n(p, end, 2, bad);
ceph_decode_skip_string(p, end, bad);
}
if (ev >= 25)
pi->last_force_request_resend = ceph_decode_32(p);
ceph_decode_32_safe(p, end, pi->last_force_request_resend, bad);
/* ignore the rest */
@ -1438,7 +1426,7 @@ static struct ceph_pg_mapping *__decode_pg_temp(void **p, void *end,
ceph_decode_32_safe(p, end, len, e_inval);
if (len == 0 && incremental)
return NULL; /* new_pg_temp: [] to remove */
if (len > (SIZE_MAX - sizeof(*pg)) / sizeof(u32))
if ((size_t)len > (SIZE_MAX - sizeof(*pg)) / sizeof(u32))
return ERR_PTR(-EINVAL);
ceph_decode_need(p, end, len * sizeof(u32), e_inval);
@ -1619,7 +1607,7 @@ static struct ceph_pg_mapping *__decode_pg_upmap_items(void **p, void *end,
u32 len, i;
ceph_decode_32_safe(p, end, len, e_inval);
if (len > (SIZE_MAX - sizeof(*pg)) / (2 * sizeof(u32)))
if ((size_t)len > (SIZE_MAX - sizeof(*pg)) / (2 * sizeof(u32)))
return ERR_PTR(-EINVAL);
ceph_decode_need(p, end, 2 * len * sizeof(u32), e_inval);

View File

@ -934,17 +934,12 @@ bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos,
#endif
if (page != dump->page) {
const unsigned int offset = pos % PAGE_SIZE;
/*
* Maybe kmap()/kunmap() should be used here.
* But remove_arg_zero() uses kmap_atomic()/kunmap_atomic().
* So do I.
*/
char *kaddr = kmap_atomic(page);
char *kaddr = kmap_local_page(page);
dump->page = page;
memcpy(dump->data + offset, kaddr + offset,
PAGE_SIZE - offset);
kunmap_atomic(kaddr);
kunmap_local(kaddr);
}
/* Same with put_arg_page(page) in fs/exec.c */
#ifdef CONFIG_MMU