* drivers/pci/p2pdma.c:536:11: warning: Dereference of null pointer [clang-analyzer-core.NullDereference]
@ 2021-12-13 0:51 kernel test robot
0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2021-12-13 0:51 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 24657 bytes --]
CC: llvm(a)lists.linux.dev
CC: kbuild-all(a)lists.01.org
CC: linux-kernel(a)vger.kernel.org
TO: Chris Down <chris@chrisdown.name>
CC: Petr Mladek <pmladek@suse.com>
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: 90d9fbc16b691403a80a119d7094528721c03279
commit: ad7d61f159db73974f1b0352f21afe04b0bbd920 printk: index: Add indexing support to dev_printk
date: 5 months ago
:::::: branch date: 6 hours ago
:::::: commit date: 5 months ago
config: x86_64-randconfig-c007-20211202 (https://download.01.org/0day-ci/archive/20211213/202112130815.a7Wl2MWZ-lkp(a)intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 4b553297ef3ee4dc2119d5429adf3072e90fac38)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ad7d61f159db73974f1b0352f21afe04b0bbd920
git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git fetch --no-tags linus master
git checkout ad7d61f159db73974f1b0352f21afe04b0bbd920
# save the config file to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 clang-analyzer
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
clang-analyzer warnings: (new ones prefixed by >>)
include/linux/compiler_types.h:328:2: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^
include/linux/compiler_types.h:316:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
include/linux/compiler_types.h:308:3: note: expanded from macro '__compiletime_assert'
if (!(condition)) \
^
drivers/pci/p2pdma.c:536:11: note: Loop condition is false. Exiting loop
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
note: (skipping 2 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
include/linux/compiler_types.h:328:2: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^
include/linux/compiler_types.h:316:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
include/linux/compiler_types.h:306:2: note: expanded from macro '__compiletime_assert'
do { \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:31: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
drivers/pci/p2pdma.c:536:11: note: Assuming the condition is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:390:19: note: expanded from macro '__rcu_dereference_check'
RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \
~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:318:8: note: expanded from macro 'RCU_LOCKDEP_WARN'
if ((c) && debug_lockdep_rcu_enabled() && !__warned) { \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '&&' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:390:2: note: expanded from macro '__rcu_dereference_check'
RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \
^
include/linux/rcupdate.h:318:11: note: expanded from macro 'RCU_LOCKDEP_WARN'
if ((c) && debug_lockdep_rcu_enabled() && !__warned) { \
^
drivers/pci/p2pdma.c:536:11: note: Loop condition is false. Exiting loop
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:390:2: note: expanded from macro '__rcu_dereference_check'
RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \
^
include/linux/rcupdate.h:316:2: note: expanded from macro 'RCU_LOCKDEP_WARN'
do { \
^
drivers/pci/p2pdma.c:537:6: note: Assuming 'p2pdma' is non-null
if (p2pdma)
^~~~~~
drivers/pci/p2pdma.c:537:2: note: Taking true branch
if (p2pdma)
^
drivers/pci/p2pdma.c:538:46: note: Passing null pointer value via 1st parameter 'client'
xa_store(&p2pdma->map_types, map_types_idx(client),
^~~~~~
drivers/pci/p2pdma.c:538:32: note: Calling 'map_types_idx'
xa_store(&p2pdma->map_types, map_types_idx(client),
^~~~~~~~~~~~~~~~~~~~~
drivers/pci/p2pdma.c:409:24: note: Access to field 'bus' results in a dereference of a null pointer (loaded from variable 'client')
return (pci_domain_nr(client->bus) << 16) |
^~~~~~
>> drivers/pci/p2pdma.c:536:11: warning: Dereference of null pointer [clang-analyzer-core.NullDereference]
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^~~~~~~~~~~~
include/asm-generic/rwonce.h:50:2: note: expanded from macro 'READ_ONCE'
__READ_ONCE(x); \
^~~~~~~~~~~~~~
include/asm-generic/rwonce.h:44:24: note: expanded from macro '__READ_ONCE'
#define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/pci/p2pdma.c:470:9: note: Assuming pointer value is null
while (a) {
^
drivers/pci/p2pdma.c:470:2: note: Loop condition is false. Execution continues on line 492
while (a) {
^
drivers/pci/p2pdma.c:493:2: note: Control jumps to line 527
goto map_through_host_bridge;
^
drivers/pci/p2pdma.c:527:29: note: Left side of '&&' is false
if (!cpu_supports_p2pdma() &&
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:21: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:290:3: note: expanded from macro '__native_word'
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:21: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:290:3: note: expanded from macro '__native_word'
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:21: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:290:3: note: expanded from macro '__native_word'
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is true
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
vim +536 drivers/pci/p2pdma.c
110203bee05f33 Logan Gunthorpe 2019-08-12 412
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 413 /*
6389d43745228d Logan Gunthorpe 2021-06-10 414 * Calculate the P2PDMA mapping type and distance between two PCI devices.
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 415 *
6389d43745228d Logan Gunthorpe 2021-06-10 416 * If the two devices are the same PCI function, return
6389d43745228d Logan Gunthorpe 2021-06-10 417 * PCI_P2PDMA_MAP_BUS_ADDR and a distance of 0.
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 418 *
6389d43745228d Logan Gunthorpe 2021-06-10 419 * If they are two functions of the same device, return
6389d43745228d Logan Gunthorpe 2021-06-10 420 * PCI_P2PDMA_MAP_BUS_ADDR and a distance of 2 (one hop up to the bridge,
6389d43745228d Logan Gunthorpe 2021-06-10 421 * then one hop back down to another function of the same device).
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 422 *
6389d43745228d Logan Gunthorpe 2021-06-10 423 * In the case where two devices are connected to the same PCIe switch,
6389d43745228d Logan Gunthorpe 2021-06-10 424 * return a distance of 4. This corresponds to the following PCI tree:
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 425 *
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 426 * -+ Root Port
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 427 * \+ Switch Upstream Port
6389d43745228d Logan Gunthorpe 2021-06-10 428 * +-+ Switch Downstream Port 0
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 429 * + \- Device A
6389d43745228d Logan Gunthorpe 2021-06-10 430 * \-+ Switch Downstream Port 1
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 431 * \- Device B
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 432 *
6389d43745228d Logan Gunthorpe 2021-06-10 433 * The distance is 4 because we traverse from Device A to Downstream Port 0
6389d43745228d Logan Gunthorpe 2021-06-10 434 * to the common Switch Upstream Port, back down to Downstream Port 1 and
6389d43745228d Logan Gunthorpe 2021-06-10 435 * then to Device B. The mapping type returned depends on the ACS
6389d43745228d Logan Gunthorpe 2021-06-10 436 * redirection setting of the ports along the path.
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 437 *
6389d43745228d Logan Gunthorpe 2021-06-10 438 * If ACS redirect is set on any port in the path, traffic between the
6389d43745228d Logan Gunthorpe 2021-06-10 439 * devices will go through the host bridge, so return
6389d43745228d Logan Gunthorpe 2021-06-10 440 * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE; otherwise return
6389d43745228d Logan Gunthorpe 2021-06-10 441 * PCI_P2PDMA_MAP_BUS_ADDR.
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 442 *
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 443 * Any two devices that have a data path that goes through the host bridge
6389d43745228d Logan Gunthorpe 2021-06-10 444 * will consult a whitelist. If the host bridge is in the whitelist, return
6389d43745228d Logan Gunthorpe 2021-06-10 445 * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE with the distance set to the number of
6389d43745228d Logan Gunthorpe 2021-06-10 446 * ports per above. If the device is not in the whitelist, return
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 447 * PCI_P2PDMA_MAP_NOT_SUPPORTED.
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 448 */
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 449 static enum pci_p2pdma_map_type
6389d43745228d Logan Gunthorpe 2021-06-10 450 calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 451 int *dist, bool verbose)
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 452 {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 453 enum pci_p2pdma_map_type map_type = PCI_P2PDMA_MAP_THRU_HOST_BRIDGE;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 454 struct pci_dev *a = provider, *b = client, *bb;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 455 bool acs_redirects = false;
ae21f835a5bda0 Eric Dumazet 2021-07-01 456 struct pci_p2pdma *p2pdma;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 457 struct seq_buf acs_list;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 458 int acs_cnt = 0;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 459 int dist_a = 0;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 460 int dist_b = 0;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 461 char buf[128];
e2cbfbf78968db Logan Gunthorpe 2019-08-12 462
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 463 seq_buf_init(&acs_list, buf, sizeof(buf));
e2cbfbf78968db Logan Gunthorpe 2019-08-12 464
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 465 /*
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 466 * Note, we don't need to take references to devices returned by
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 467 * pci_upstream_bridge() seeing we hold a reference to a child
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 468 * device which will already hold a reference to the upstream bridge.
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 469 */
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 470 while (a) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 471 dist_b = 0;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 472
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 473 if (pci_bridge_has_acs_redir(a)) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 474 seq_buf_print_bus_devfn(&acs_list, a);
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 475 acs_cnt++;
e2cbfbf78968db Logan Gunthorpe 2019-08-12 476 }
e2cbfbf78968db Logan Gunthorpe 2019-08-12 477
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 478 bb = b;
110203bee05f33 Logan Gunthorpe 2019-08-12 479
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 480 while (bb) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 481 if (a == bb)
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 482 goto check_b_path_acs;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 483
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 484 bb = pci_upstream_bridge(bb);
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 485 dist_b++;
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 486 }
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 487
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 488 a = pci_upstream_bridge(a);
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 489 dist_a++;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 490 }
52916982af48d9 Logan Gunthorpe 2018-10-04 491
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 492 *dist = dist_a + dist_b;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 493 goto map_through_host_bridge;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 494
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 495 check_b_path_acs:
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 496 bb = b;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 497
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 498 while (bb) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 499 if (a == bb)
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 500 break;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 501
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 502 if (pci_bridge_has_acs_redir(bb)) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 503 seq_buf_print_bus_devfn(&acs_list, bb);
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 504 acs_cnt++;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 505 }
52916982af48d9 Logan Gunthorpe 2018-10-04 506
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 507 bb = pci_upstream_bridge(bb);
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 508 }
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 509
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 510 *dist = dist_a + dist_b;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 511
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 512 if (!acs_cnt) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 513 map_type = PCI_P2PDMA_MAP_BUS_ADDR;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 514 goto done;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 515 }
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 516
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 517 if (verbose) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 518 acs_list.buffer[acs_list.len-1] = 0; /* drop final semicolon */
72583084e3fe33 Logan Gunthorpe 2019-08-12 519 pci_warn(client, "ACS redirect is set between the client and provider (%s)\n",
52916982af48d9 Logan Gunthorpe 2018-10-04 520 pci_name(provider));
52916982af48d9 Logan Gunthorpe 2018-10-04 521 pci_warn(client, "to disable ACS redirect for this path, add the kernel parameter: pci=disable_acs_redir=%s\n",
52916982af48d9 Logan Gunthorpe 2018-10-04 522 acs_list.buffer);
72583084e3fe33 Logan Gunthorpe 2019-08-12 523 }
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 524 acs_redirects = true;
52916982af48d9 Logan Gunthorpe 2018-10-04 525
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 526 map_through_host_bridge:
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 527 if (!cpu_supports_p2pdma() &&
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 528 !host_bridge_whitelist(provider, client, acs_redirects)) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 529 if (verbose)
72583084e3fe33 Logan Gunthorpe 2019-08-12 530 pci_warn(client, "cannot be used for peer-to-peer DMA as the client and provider (%s) do not share an upstream bridge or whitelisted host bridge\n",
52916982af48d9 Logan Gunthorpe 2018-10-04 531 pci_name(provider));
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 532 map_type = PCI_P2PDMA_MAP_NOT_SUPPORTED;
52916982af48d9 Logan Gunthorpe 2018-10-04 533 }
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 534 done:
ae21f835a5bda0 Eric Dumazet 2021-07-01 535 rcu_read_lock();
ae21f835a5bda0 Eric Dumazet 2021-07-01 @536 p2pdma = rcu_dereference(provider->p2pdma);
ae21f835a5bda0 Eric Dumazet 2021-07-01 537 if (p2pdma)
ae21f835a5bda0 Eric Dumazet 2021-07-01 538 xa_store(&p2pdma->map_types, map_types_idx(client),
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 539 xa_mk_value(map_type), GFP_KERNEL);
ae21f835a5bda0 Eric Dumazet 2021-07-01 540 rcu_read_unlock();
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 541 return map_type;
52916982af48d9 Logan Gunthorpe 2018-10-04 542 }
52916982af48d9 Logan Gunthorpe 2018-10-04 543
:::::: The code at line 536 was first introduced by commit
:::::: ae21f835a5bda0ef1d00940373445693a764d89e PCI/P2PDMA: Finish RCU conversion of pdev->p2pdma
:::::: TO: Eric Dumazet <edumazet@google.com>
:::::: CC: Bjorn Helgaas <bhelgaas@google.com>
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
^ permalink raw reply [flat|nested] 4+ messages in thread
* drivers/pci/p2pdma.c:536:11: warning: Dereference of null pointer [clang-analyzer-core.NullDereference]
@ 2021-12-18 21:00 kernel test robot
0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2021-12-18 21:00 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 24790 bytes --]
CC: llvm(a)lists.linux.dev
CC: kbuild-all(a)lists.01.org
CC: linux-kernel(a)vger.kernel.org
TO: Chris Down <chris@chrisdown.name>
CC: Petr Mladek <pmladek@suse.com>
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: 9eaa88c7036eda3f6c215f87ca693594cf90559b
commit: ad7d61f159db73974f1b0352f21afe04b0bbd920 printk: index: Add indexing support to dev_printk
date: 5 months ago
:::::: branch date: 20 hours ago
:::::: commit date: 5 months ago
config: x86_64-randconfig-c007-20211202 (https://download.01.org/0day-ci/archive/20211219/202112190408.h8APic0f-lkp(a)intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 4b553297ef3ee4dc2119d5429adf3072e90fac38)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ad7d61f159db73974f1b0352f21afe04b0bbd920
git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git fetch --no-tags linus master
git checkout ad7d61f159db73974f1b0352f21afe04b0bbd920
# save the config file to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 clang-analyzer
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
clang-analyzer warnings: (new ones prefixed by >>)
include/linux/compiler_types.h:328:2: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^
include/linux/compiler_types.h:316:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
include/linux/compiler_types.h:308:3: note: expanded from macro '__compiletime_assert'
if (!(condition)) \
^
drivers/pci/p2pdma.c:536:11: note: Loop condition is false. Exiting loop
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
note: (skipping 2 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
include/linux/compiler_types.h:328:2: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^
include/linux/compiler_types.h:316:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
include/linux/compiler_types.h:306:2: note: expanded from macro '__compiletime_assert'
do { \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:31: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
drivers/pci/p2pdma.c:536:11: note: Assuming the condition is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:390:19: note: expanded from macro '__rcu_dereference_check'
RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \
~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:318:8: note: expanded from macro 'RCU_LOCKDEP_WARN'
if ((c) && debug_lockdep_rcu_enabled() && !__warned) { \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '&&' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:390:2: note: expanded from macro '__rcu_dereference_check'
RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \
^
include/linux/rcupdate.h:318:11: note: expanded from macro 'RCU_LOCKDEP_WARN'
if ((c) && debug_lockdep_rcu_enabled() && !__warned) { \
^
drivers/pci/p2pdma.c:536:11: note: Loop condition is false. Exiting loop
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:390:2: note: expanded from macro '__rcu_dereference_check'
RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \
^
include/linux/rcupdate.h:316:2: note: expanded from macro 'RCU_LOCKDEP_WARN'
do { \
^
drivers/pci/p2pdma.c:537:6: note: Assuming 'p2pdma' is non-null
if (p2pdma)
^~~~~~
drivers/pci/p2pdma.c:537:2: note: Taking true branch
if (p2pdma)
^
drivers/pci/p2pdma.c:538:46: note: Passing null pointer value via 1st parameter 'client'
xa_store(&p2pdma->map_types, map_types_idx(client),
^~~~~~
drivers/pci/p2pdma.c:538:32: note: Calling 'map_types_idx'
xa_store(&p2pdma->map_types, map_types_idx(client),
^~~~~~~~~~~~~~~~~~~~~
drivers/pci/p2pdma.c:409:24: note: Access to field 'bus' results in a dereference of a null pointer (loaded from variable 'client')
return (pci_domain_nr(client->bus) << 16) |
^~~~~~
>> drivers/pci/p2pdma.c:536:11: warning: Dereference of null pointer [clang-analyzer-core.NullDereference]
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^~~~~~~~~~~~
include/asm-generic/rwonce.h:50:2: note: expanded from macro 'READ_ONCE'
__READ_ONCE(x); \
^~~~~~~~~~~~~~
include/asm-generic/rwonce.h:44:24: note: expanded from macro '__READ_ONCE'
#define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/pci/p2pdma.c:470:9: note: Assuming pointer value is null
while (a) {
^
drivers/pci/p2pdma.c:470:2: note: Loop condition is false. Execution continues on line 492
while (a) {
^
drivers/pci/p2pdma.c:493:2: note: Control jumps to line 527
goto map_through_host_bridge;
^
drivers/pci/p2pdma.c:527:29: note: Left side of '&&' is false
if (!cpu_supports_p2pdma() &&
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:21: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:290:3: note: expanded from macro '__native_word'
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:21: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:290:3: note: expanded from macro '__native_word'
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:21: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:290:3: note: expanded from macro '__native_word'
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is true
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
vim +536 drivers/pci/p2pdma.c
110203bee05f336 Logan Gunthorpe 2019-08-12 412
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 413 /*
6389d43745228de Logan Gunthorpe 2021-06-10 414 * Calculate the P2PDMA mapping type and distance between two PCI devices.
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 415 *
6389d43745228de Logan Gunthorpe 2021-06-10 416 * If the two devices are the same PCI function, return
6389d43745228de Logan Gunthorpe 2021-06-10 417 * PCI_P2PDMA_MAP_BUS_ADDR and a distance of 0.
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 418 *
6389d43745228de Logan Gunthorpe 2021-06-10 419 * If they are two functions of the same device, return
6389d43745228de Logan Gunthorpe 2021-06-10 420 * PCI_P2PDMA_MAP_BUS_ADDR and a distance of 2 (one hop up to the bridge,
6389d43745228de Logan Gunthorpe 2021-06-10 421 * then one hop back down to another function of the same device).
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 422 *
6389d43745228de Logan Gunthorpe 2021-06-10 423 * In the case where two devices are connected to the same PCIe switch,
6389d43745228de Logan Gunthorpe 2021-06-10 424 * return a distance of 4. This corresponds to the following PCI tree:
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 425 *
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 426 * -+ Root Port
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 427 * \+ Switch Upstream Port
6389d43745228de Logan Gunthorpe 2021-06-10 428 * +-+ Switch Downstream Port 0
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 429 * + \- Device A
6389d43745228de Logan Gunthorpe 2021-06-10 430 * \-+ Switch Downstream Port 1
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 431 * \- Device B
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 432 *
6389d43745228de Logan Gunthorpe 2021-06-10 433 * The distance is 4 because we traverse from Device A to Downstream Port 0
6389d43745228de Logan Gunthorpe 2021-06-10 434 * to the common Switch Upstream Port, back down to Downstream Port 1 and
6389d43745228de Logan Gunthorpe 2021-06-10 435 * then to Device B. The mapping type returned depends on the ACS
6389d43745228de Logan Gunthorpe 2021-06-10 436 * redirection setting of the ports along the path.
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 437 *
6389d43745228de Logan Gunthorpe 2021-06-10 438 * If ACS redirect is set on any port in the path, traffic between the
6389d43745228de Logan Gunthorpe 2021-06-10 439 * devices will go through the host bridge, so return
6389d43745228de Logan Gunthorpe 2021-06-10 440 * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE; otherwise return
6389d43745228de Logan Gunthorpe 2021-06-10 441 * PCI_P2PDMA_MAP_BUS_ADDR.
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 442 *
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 443 * Any two devices that have a data path that goes through the host bridge
6389d43745228de Logan Gunthorpe 2021-06-10 444 * will consult a whitelist. If the host bridge is in the whitelist, return
6389d43745228de Logan Gunthorpe 2021-06-10 445 * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE with the distance set to the number of
6389d43745228de Logan Gunthorpe 2021-06-10 446 * ports per above. If the device is not in the whitelist, return
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 447 * PCI_P2PDMA_MAP_NOT_SUPPORTED.
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 448 */
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 449 static enum pci_p2pdma_map_type
6389d43745228de Logan Gunthorpe 2021-06-10 450 calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 451 int *dist, bool verbose)
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 452 {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 453 enum pci_p2pdma_map_type map_type = PCI_P2PDMA_MAP_THRU_HOST_BRIDGE;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 454 struct pci_dev *a = provider, *b = client, *bb;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 455 bool acs_redirects = false;
ae21f835a5bda0e Eric Dumazet 2021-07-01 456 struct pci_p2pdma *p2pdma;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 457 struct seq_buf acs_list;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 458 int acs_cnt = 0;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 459 int dist_a = 0;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 460 int dist_b = 0;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 461 char buf[128];
e2cbfbf78968db3 Logan Gunthorpe 2019-08-12 462
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 463 seq_buf_init(&acs_list, buf, sizeof(buf));
e2cbfbf78968db3 Logan Gunthorpe 2019-08-12 464
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 465 /*
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 466 * Note, we don't need to take references to devices returned by
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 467 * pci_upstream_bridge() seeing we hold a reference to a child
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 468 * device which will already hold a reference to the upstream bridge.
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 469 */
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 470 while (a) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 471 dist_b = 0;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 472
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 473 if (pci_bridge_has_acs_redir(a)) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 474 seq_buf_print_bus_devfn(&acs_list, a);
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 475 acs_cnt++;
e2cbfbf78968db3 Logan Gunthorpe 2019-08-12 476 }
e2cbfbf78968db3 Logan Gunthorpe 2019-08-12 477
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 478 bb = b;
110203bee05f336 Logan Gunthorpe 2019-08-12 479
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 480 while (bb) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 481 if (a == bb)
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 482 goto check_b_path_acs;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 483
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 484 bb = pci_upstream_bridge(bb);
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 485 dist_b++;
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 486 }
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 487
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 488 a = pci_upstream_bridge(a);
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 489 dist_a++;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 490 }
52916982af48d9f Logan Gunthorpe 2018-10-04 491
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 492 *dist = dist_a + dist_b;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 493 goto map_through_host_bridge;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 494
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 495 check_b_path_acs:
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 496 bb = b;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 497
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 498 while (bb) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 499 if (a == bb)
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 500 break;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 501
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 502 if (pci_bridge_has_acs_redir(bb)) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 503 seq_buf_print_bus_devfn(&acs_list, bb);
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 504 acs_cnt++;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 505 }
52916982af48d9f Logan Gunthorpe 2018-10-04 506
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 507 bb = pci_upstream_bridge(bb);
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 508 }
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 509
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 510 *dist = dist_a + dist_b;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 511
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 512 if (!acs_cnt) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 513 map_type = PCI_P2PDMA_MAP_BUS_ADDR;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 514 goto done;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 515 }
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 516
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 517 if (verbose) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 518 acs_list.buffer[acs_list.len-1] = 0; /* drop final semicolon */
72583084e3fe333 Logan Gunthorpe 2019-08-12 519 pci_warn(client, "ACS redirect is set between the client and provider (%s)\n",
52916982af48d9f Logan Gunthorpe 2018-10-04 520 pci_name(provider));
52916982af48d9f Logan Gunthorpe 2018-10-04 521 pci_warn(client, "to disable ACS redirect for this path, add the kernel parameter: pci=disable_acs_redir=%s\n",
52916982af48d9f Logan Gunthorpe 2018-10-04 522 acs_list.buffer);
72583084e3fe333 Logan Gunthorpe 2019-08-12 523 }
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 524 acs_redirects = true;
52916982af48d9f Logan Gunthorpe 2018-10-04 525
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 526 map_through_host_bridge:
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 527 if (!cpu_supports_p2pdma() &&
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 528 !host_bridge_whitelist(provider, client, acs_redirects)) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 529 if (verbose)
72583084e3fe333 Logan Gunthorpe 2019-08-12 530 pci_warn(client, "cannot be used for peer-to-peer DMA as the client and provider (%s) do not share an upstream bridge or whitelisted host bridge\n",
52916982af48d9f Logan Gunthorpe 2018-10-04 531 pci_name(provider));
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 532 map_type = PCI_P2PDMA_MAP_NOT_SUPPORTED;
52916982af48d9f Logan Gunthorpe 2018-10-04 533 }
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 534 done:
ae21f835a5bda0e Eric Dumazet 2021-07-01 535 rcu_read_lock();
ae21f835a5bda0e Eric Dumazet 2021-07-01 @536 p2pdma = rcu_dereference(provider->p2pdma);
ae21f835a5bda0e Eric Dumazet 2021-07-01 537 if (p2pdma)
ae21f835a5bda0e Eric Dumazet 2021-07-01 538 xa_store(&p2pdma->map_types, map_types_idx(client),
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 539 xa_mk_value(map_type), GFP_KERNEL);
ae21f835a5bda0e Eric Dumazet 2021-07-01 540 rcu_read_unlock();
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 541 return map_type;
52916982af48d9f Logan Gunthorpe 2018-10-04 542 }
52916982af48d9f Logan Gunthorpe 2018-10-04 543
:::::: The code at line 536 was first introduced by commit
:::::: ae21f835a5bda0ef1d00940373445693a764d89e PCI/P2PDMA: Finish RCU conversion of pdev->p2pdma
:::::: TO: Eric Dumazet <edumazet@google.com>
:::::: CC: Bjorn Helgaas <bhelgaas@google.com>
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
^ permalink raw reply [flat|nested] 4+ messages in thread
* drivers/pci/p2pdma.c:536:11: warning: Dereference of null pointer [clang-analyzer-core.NullDereference]
@ 2021-12-09 22:25 kernel test robot
0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2021-12-09 22:25 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 24789 bytes --]
CC: llvm(a)lists.linux.dev
CC: kbuild-all(a)lists.01.org
CC: linux-kernel(a)vger.kernel.org
TO: Chris Down <chris@chrisdown.name>
CC: Petr Mladek <pmladek@suse.com>
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: ded746bfc94398d2ee9de315a187677b207b2004
commit: ad7d61f159db73974f1b0352f21afe04b0bbd920 printk: index: Add indexing support to dev_printk
date: 5 months ago
:::::: branch date: 3 hours ago
:::::: commit date: 5 months ago
config: x86_64-randconfig-c007-20211202 (https://download.01.org/0day-ci/archive/20211210/202112100628.muNoiwX0-lkp(a)intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 4b553297ef3ee4dc2119d5429adf3072e90fac38)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ad7d61f159db73974f1b0352f21afe04b0bbd920
git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git fetch --no-tags linus master
git checkout ad7d61f159db73974f1b0352f21afe04b0bbd920
# save the config file to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 clang-analyzer
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
clang-analyzer warnings: (new ones prefixed by >>)
include/linux/compiler_types.h:328:2: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^
include/linux/compiler_types.h:316:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
include/linux/compiler_types.h:308:3: note: expanded from macro '__compiletime_assert'
if (!(condition)) \
^
drivers/pci/p2pdma.c:536:11: note: Loop condition is false. Exiting loop
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
note: (skipping 2 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
include/linux/compiler_types.h:328:2: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^
include/linux/compiler_types.h:316:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
include/linux/compiler_types.h:306:2: note: expanded from macro '__compiletime_assert'
do { \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:31: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
drivers/pci/p2pdma.c:536:11: note: Assuming the condition is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:390:19: note: expanded from macro '__rcu_dereference_check'
RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \
~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:318:8: note: expanded from macro 'RCU_LOCKDEP_WARN'
if ((c) && debug_lockdep_rcu_enabled() && !__warned) { \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '&&' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:390:2: note: expanded from macro '__rcu_dereference_check'
RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \
^
include/linux/rcupdate.h:318:11: note: expanded from macro 'RCU_LOCKDEP_WARN'
if ((c) && debug_lockdep_rcu_enabled() && !__warned) { \
^
drivers/pci/p2pdma.c:536:11: note: Loop condition is false. Exiting loop
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:390:2: note: expanded from macro '__rcu_dereference_check'
RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \
^
include/linux/rcupdate.h:316:2: note: expanded from macro 'RCU_LOCKDEP_WARN'
do { \
^
drivers/pci/p2pdma.c:537:6: note: Assuming 'p2pdma' is non-null
if (p2pdma)
^~~~~~
drivers/pci/p2pdma.c:537:2: note: Taking true branch
if (p2pdma)
^
drivers/pci/p2pdma.c:538:46: note: Passing null pointer value via 1st parameter 'client'
xa_store(&p2pdma->map_types, map_types_idx(client),
^~~~~~
drivers/pci/p2pdma.c:538:32: note: Calling 'map_types_idx'
xa_store(&p2pdma->map_types, map_types_idx(client),
^~~~~~~~~~~~~~~~~~~~~
drivers/pci/p2pdma.c:409:24: note: Access to field 'bus' results in a dereference of a null pointer (loaded from variable 'client')
return (pci_domain_nr(client->bus) << 16) |
^~~~~~
>> drivers/pci/p2pdma.c:536:11: warning: Dereference of null pointer [clang-analyzer-core.NullDereference]
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^~~~~~~~~~~~
include/asm-generic/rwonce.h:50:2: note: expanded from macro 'READ_ONCE'
__READ_ONCE(x); \
^~~~~~~~~~~~~~
include/asm-generic/rwonce.h:44:24: note: expanded from macro '__READ_ONCE'
#define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/pci/p2pdma.c:470:9: note: Assuming pointer value is null
while (a) {
^
drivers/pci/p2pdma.c:470:2: note: Loop condition is false. Execution continues on line 492
while (a) {
^
drivers/pci/p2pdma.c:493:2: note: Control jumps to line 527
goto map_through_host_bridge;
^
drivers/pci/p2pdma.c:527:29: note: Left side of '&&' is false
if (!cpu_supports_p2pdma() &&
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:21: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:290:3: note: expanded from macro '__native_word'
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:21: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:290:3: note: expanded from macro '__native_word'
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:21: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:290:3: note: expanded from macro '__native_word'
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is true
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
vim +536 drivers/pci/p2pdma.c
110203bee05f336 Logan Gunthorpe 2019-08-12 412
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 413 /*
6389d43745228de Logan Gunthorpe 2021-06-10 414 * Calculate the P2PDMA mapping type and distance between two PCI devices.
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 415 *
6389d43745228de Logan Gunthorpe 2021-06-10 416 * If the two devices are the same PCI function, return
6389d43745228de Logan Gunthorpe 2021-06-10 417 * PCI_P2PDMA_MAP_BUS_ADDR and a distance of 0.
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 418 *
6389d43745228de Logan Gunthorpe 2021-06-10 419 * If they are two functions of the same device, return
6389d43745228de Logan Gunthorpe 2021-06-10 420 * PCI_P2PDMA_MAP_BUS_ADDR and a distance of 2 (one hop up to the bridge,
6389d43745228de Logan Gunthorpe 2021-06-10 421 * then one hop back down to another function of the same device).
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 422 *
6389d43745228de Logan Gunthorpe 2021-06-10 423 * In the case where two devices are connected to the same PCIe switch,
6389d43745228de Logan Gunthorpe 2021-06-10 424 * return a distance of 4. This corresponds to the following PCI tree:
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 425 *
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 426 * -+ Root Port
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 427 * \+ Switch Upstream Port
6389d43745228de Logan Gunthorpe 2021-06-10 428 * +-+ Switch Downstream Port 0
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 429 * + \- Device A
6389d43745228de Logan Gunthorpe 2021-06-10 430 * \-+ Switch Downstream Port 1
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 431 * \- Device B
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 432 *
6389d43745228de Logan Gunthorpe 2021-06-10 433 * The distance is 4 because we traverse from Device A to Downstream Port 0
6389d43745228de Logan Gunthorpe 2021-06-10 434 * to the common Switch Upstream Port, back down to Downstream Port 1 and
6389d43745228de Logan Gunthorpe 2021-06-10 435 * then to Device B. The mapping type returned depends on the ACS
6389d43745228de Logan Gunthorpe 2021-06-10 436 * redirection setting of the ports along the path.
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 437 *
6389d43745228de Logan Gunthorpe 2021-06-10 438 * If ACS redirect is set on any port in the path, traffic between the
6389d43745228de Logan Gunthorpe 2021-06-10 439 * devices will go through the host bridge, so return
6389d43745228de Logan Gunthorpe 2021-06-10 440 * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE; otherwise return
6389d43745228de Logan Gunthorpe 2021-06-10 441 * PCI_P2PDMA_MAP_BUS_ADDR.
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 442 *
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 443 * Any two devices that have a data path that goes through the host bridge
6389d43745228de Logan Gunthorpe 2021-06-10 444 * will consult a whitelist. If the host bridge is in the whitelist, return
6389d43745228de Logan Gunthorpe 2021-06-10 445 * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE with the distance set to the number of
6389d43745228de Logan Gunthorpe 2021-06-10 446 * ports per above. If the device is not in the whitelist, return
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 447 * PCI_P2PDMA_MAP_NOT_SUPPORTED.
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 448 */
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 449 static enum pci_p2pdma_map_type
6389d43745228de Logan Gunthorpe 2021-06-10 450 calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 451 int *dist, bool verbose)
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 452 {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 453 enum pci_p2pdma_map_type map_type = PCI_P2PDMA_MAP_THRU_HOST_BRIDGE;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 454 struct pci_dev *a = provider, *b = client, *bb;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 455 bool acs_redirects = false;
ae21f835a5bda0e Eric Dumazet 2021-07-01 456 struct pci_p2pdma *p2pdma;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 457 struct seq_buf acs_list;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 458 int acs_cnt = 0;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 459 int dist_a = 0;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 460 int dist_b = 0;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 461 char buf[128];
e2cbfbf78968db3 Logan Gunthorpe 2019-08-12 462
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 463 seq_buf_init(&acs_list, buf, sizeof(buf));
e2cbfbf78968db3 Logan Gunthorpe 2019-08-12 464
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 465 /*
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 466 * Note, we don't need to take references to devices returned by
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 467 * pci_upstream_bridge() seeing we hold a reference to a child
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 468 * device which will already hold a reference to the upstream bridge.
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 469 */
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 470 while (a) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 471 dist_b = 0;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 472
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 473 if (pci_bridge_has_acs_redir(a)) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 474 seq_buf_print_bus_devfn(&acs_list, a);
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 475 acs_cnt++;
e2cbfbf78968db3 Logan Gunthorpe 2019-08-12 476 }
e2cbfbf78968db3 Logan Gunthorpe 2019-08-12 477
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 478 bb = b;
110203bee05f336 Logan Gunthorpe 2019-08-12 479
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 480 while (bb) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 481 if (a == bb)
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 482 goto check_b_path_acs;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 483
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 484 bb = pci_upstream_bridge(bb);
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 485 dist_b++;
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 486 }
c6bfaeb573a6caa Logan Gunthorpe 2019-08-12 487
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 488 a = pci_upstream_bridge(a);
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 489 dist_a++;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 490 }
52916982af48d9f Logan Gunthorpe 2018-10-04 491
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 492 *dist = dist_a + dist_b;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 493 goto map_through_host_bridge;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 494
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 495 check_b_path_acs:
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 496 bb = b;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 497
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 498 while (bb) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 499 if (a == bb)
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 500 break;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 501
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 502 if (pci_bridge_has_acs_redir(bb)) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 503 seq_buf_print_bus_devfn(&acs_list, bb);
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 504 acs_cnt++;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 505 }
52916982af48d9f Logan Gunthorpe 2018-10-04 506
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 507 bb = pci_upstream_bridge(bb);
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 508 }
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 509
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 510 *dist = dist_a + dist_b;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 511
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 512 if (!acs_cnt) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 513 map_type = PCI_P2PDMA_MAP_BUS_ADDR;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 514 goto done;
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 515 }
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 516
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 517 if (verbose) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 518 acs_list.buffer[acs_list.len-1] = 0; /* drop final semicolon */
72583084e3fe333 Logan Gunthorpe 2019-08-12 519 pci_warn(client, "ACS redirect is set between the client and provider (%s)\n",
52916982af48d9f Logan Gunthorpe 2018-10-04 520 pci_name(provider));
52916982af48d9f Logan Gunthorpe 2018-10-04 521 pci_warn(client, "to disable ACS redirect for this path, add the kernel parameter: pci=disable_acs_redir=%s\n",
52916982af48d9f Logan Gunthorpe 2018-10-04 522 acs_list.buffer);
72583084e3fe333 Logan Gunthorpe 2019-08-12 523 }
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 524 acs_redirects = true;
52916982af48d9f Logan Gunthorpe 2018-10-04 525
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 526 map_through_host_bridge:
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 527 if (!cpu_supports_p2pdma() &&
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 528 !host_bridge_whitelist(provider, client, acs_redirects)) {
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 529 if (verbose)
72583084e3fe333 Logan Gunthorpe 2019-08-12 530 pci_warn(client, "cannot be used for peer-to-peer DMA as the client and provider (%s) do not share an upstream bridge or whitelisted host bridge\n",
52916982af48d9f Logan Gunthorpe 2018-10-04 531 pci_name(provider));
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 532 map_type = PCI_P2PDMA_MAP_NOT_SUPPORTED;
52916982af48d9f Logan Gunthorpe 2018-10-04 533 }
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 534 done:
ae21f835a5bda0e Eric Dumazet 2021-07-01 535 rcu_read_lock();
ae21f835a5bda0e Eric Dumazet 2021-07-01 @536 p2pdma = rcu_dereference(provider->p2pdma);
ae21f835a5bda0e Eric Dumazet 2021-07-01 537 if (p2pdma)
ae21f835a5bda0e Eric Dumazet 2021-07-01 538 xa_store(&p2pdma->map_types, map_types_idx(client),
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 539 xa_mk_value(map_type), GFP_KERNEL);
ae21f835a5bda0e Eric Dumazet 2021-07-01 540 rcu_read_unlock();
d1b8dc09dd71248 Christoph Hellwig 2021-06-14 541 return map_type;
52916982af48d9f Logan Gunthorpe 2018-10-04 542 }
52916982af48d9f Logan Gunthorpe 2018-10-04 543
:::::: The code at line 536 was first introduced by commit
:::::: ae21f835a5bda0ef1d00940373445693a764d89e PCI/P2PDMA: Finish RCU conversion of pdev->p2pdma
:::::: TO: Eric Dumazet <edumazet@google.com>
:::::: CC: Bjorn Helgaas <bhelgaas@google.com>
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
^ permalink raw reply [flat|nested] 4+ messages in thread
* drivers/pci/p2pdma.c:536:11: warning: Dereference of null pointer [clang-analyzer-core.NullDereference]
@ 2021-12-08 23:13 kernel test robot
0 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2021-12-08 23:13 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 24658 bytes --]
CC: llvm(a)lists.linux.dev
CC: kbuild-all(a)lists.01.org
CC: linux-kernel(a)vger.kernel.org
TO: Chris Down <chris@chrisdown.name>
CC: Petr Mladek <pmladek@suse.com>
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: 2a987e65025e2b79c6d453b78cb5985ac6e5eb26
commit: ad7d61f159db73974f1b0352f21afe04b0bbd920 printk: index: Add indexing support to dev_printk
date: 5 months ago
:::::: branch date: 24 hours ago
:::::: commit date: 5 months ago
config: x86_64-randconfig-c007-20211202 (https://download.01.org/0day-ci/archive/20211209/202112090734.vometa8g-lkp(a)intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 4b553297ef3ee4dc2119d5429adf3072e90fac38)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ad7d61f159db73974f1b0352f21afe04b0bbd920
git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git fetch --no-tags linus master
git checkout ad7d61f159db73974f1b0352f21afe04b0bbd920
# save the config file to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 clang-analyzer
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
clang-analyzer warnings: (new ones prefixed by >>)
include/linux/compiler_types.h:328:2: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^
include/linux/compiler_types.h:316:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
include/linux/compiler_types.h:308:3: note: expanded from macro '__compiletime_assert'
if (!(condition)) \
^
drivers/pci/p2pdma.c:536:11: note: Loop condition is false. Exiting loop
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
note: (skipping 2 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
include/linux/compiler_types.h:328:2: note: expanded from macro 'compiletime_assert'
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^
include/linux/compiler_types.h:316:2: note: expanded from macro '_compiletime_assert'
__compiletime_assert(condition, msg, prefix, suffix)
^
include/linux/compiler_types.h:306:2: note: expanded from macro '__compiletime_assert'
do { \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:31: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
drivers/pci/p2pdma.c:536:11: note: Assuming the condition is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:390:19: note: expanded from macro '__rcu_dereference_check'
RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \
~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:318:8: note: expanded from macro 'RCU_LOCKDEP_WARN'
if ((c) && debug_lockdep_rcu_enabled() && !__warned) { \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '&&' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:390:2: note: expanded from macro '__rcu_dereference_check'
RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \
^
include/linux/rcupdate.h:318:11: note: expanded from macro 'RCU_LOCKDEP_WARN'
if ((c) && debug_lockdep_rcu_enabled() && !__warned) { \
^
drivers/pci/p2pdma.c:536:11: note: Loop condition is false. Exiting loop
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:390:2: note: expanded from macro '__rcu_dereference_check'
RCU_LOCKDEP_WARN(!(c), "suspicious rcu_dereference_check() usage"); \
^
include/linux/rcupdate.h:316:2: note: expanded from macro 'RCU_LOCKDEP_WARN'
do { \
^
drivers/pci/p2pdma.c:537:6: note: Assuming 'p2pdma' is non-null
if (p2pdma)
^~~~~~
drivers/pci/p2pdma.c:537:2: note: Taking true branch
if (p2pdma)
^
drivers/pci/p2pdma.c:538:46: note: Passing null pointer value via 1st parameter 'client'
xa_store(&p2pdma->map_types, map_types_idx(client),
^~~~~~
drivers/pci/p2pdma.c:538:32: note: Calling 'map_types_idx'
xa_store(&p2pdma->map_types, map_types_idx(client),
^~~~~~~~~~~~~~~~~~~~~
drivers/pci/p2pdma.c:409:24: note: Access to field 'bus' results in a dereference of a null pointer (loaded from variable 'client')
return (pci_domain_nr(client->bus) << 16) |
^~~~~~
>> drivers/pci/p2pdma.c:536:11: warning: Dereference of null pointer [clang-analyzer-core.NullDereference]
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^~~~~~~~~~~~
include/asm-generic/rwonce.h:50:2: note: expanded from macro 'READ_ONCE'
__READ_ONCE(x); \
^~~~~~~~~~~~~~
include/asm-generic/rwonce.h:44:24: note: expanded from macro '__READ_ONCE'
#define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/pci/p2pdma.c:470:9: note: Assuming pointer value is null
while (a) {
^
drivers/pci/p2pdma.c:470:2: note: Loop condition is false. Execution continues on line 492
while (a) {
^
drivers/pci/p2pdma.c:493:2: note: Control jumps to line 527
goto map_through_host_bridge;
^
drivers/pci/p2pdma.c:527:29: note: Left side of '&&' is false
if (!cpu_supports_p2pdma() &&
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:21: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:290:3: note: expanded from macro '__native_word'
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:21: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:290:3: note: expanded from macro '__native_word'
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is false
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
^
include/linux/rcupdate.h:389:48: note: expanded from macro '__rcu_dereference_check'
typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
^
include/asm-generic/rwonce.h:49:2: note: expanded from macro 'READ_ONCE'
compiletime_assert_rwonce_type(x); \
^
include/asm-generic/rwonce.h:36:21: note: expanded from macro 'compiletime_assert_rwonce_type'
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
^
include/linux/compiler_types.h:290:3: note: expanded from macro '__native_word'
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
^
drivers/pci/p2pdma.c:536:11: note: Left side of '||' is true
p2pdma = rcu_dereference(provider->p2pdma);
^
include/linux/rcupdate.h:596:28: note: expanded from macro 'rcu_dereference'
#define rcu_dereference(p) rcu_dereference_check(p, 0)
^
include/linux/rcupdate.h:528:2: note: expanded from macro 'rcu_dereference_check'
__rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
vim +536 drivers/pci/p2pdma.c
110203bee05f33 Logan Gunthorpe 2019-08-12 412
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 413 /*
6389d43745228d Logan Gunthorpe 2021-06-10 414 * Calculate the P2PDMA mapping type and distance between two PCI devices.
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 415 *
6389d43745228d Logan Gunthorpe 2021-06-10 416 * If the two devices are the same PCI function, return
6389d43745228d Logan Gunthorpe 2021-06-10 417 * PCI_P2PDMA_MAP_BUS_ADDR and a distance of 0.
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 418 *
6389d43745228d Logan Gunthorpe 2021-06-10 419 * If they are two functions of the same device, return
6389d43745228d Logan Gunthorpe 2021-06-10 420 * PCI_P2PDMA_MAP_BUS_ADDR and a distance of 2 (one hop up to the bridge,
6389d43745228d Logan Gunthorpe 2021-06-10 421 * then one hop back down to another function of the same device).
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 422 *
6389d43745228d Logan Gunthorpe 2021-06-10 423 * In the case where two devices are connected to the same PCIe switch,
6389d43745228d Logan Gunthorpe 2021-06-10 424 * return a distance of 4. This corresponds to the following PCI tree:
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 425 *
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 426 * -+ Root Port
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 427 * \+ Switch Upstream Port
6389d43745228d Logan Gunthorpe 2021-06-10 428 * +-+ Switch Downstream Port 0
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 429 * + \- Device A
6389d43745228d Logan Gunthorpe 2021-06-10 430 * \-+ Switch Downstream Port 1
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 431 * \- Device B
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 432 *
6389d43745228d Logan Gunthorpe 2021-06-10 433 * The distance is 4 because we traverse from Device A to Downstream Port 0
6389d43745228d Logan Gunthorpe 2021-06-10 434 * to the common Switch Upstream Port, back down to Downstream Port 1 and
6389d43745228d Logan Gunthorpe 2021-06-10 435 * then to Device B. The mapping type returned depends on the ACS
6389d43745228d Logan Gunthorpe 2021-06-10 436 * redirection setting of the ports along the path.
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 437 *
6389d43745228d Logan Gunthorpe 2021-06-10 438 * If ACS redirect is set on any port in the path, traffic between the
6389d43745228d Logan Gunthorpe 2021-06-10 439 * devices will go through the host bridge, so return
6389d43745228d Logan Gunthorpe 2021-06-10 440 * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE; otherwise return
6389d43745228d Logan Gunthorpe 2021-06-10 441 * PCI_P2PDMA_MAP_BUS_ADDR.
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 442 *
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 443 * Any two devices that have a data path that goes through the host bridge
6389d43745228d Logan Gunthorpe 2021-06-10 444 * will consult a whitelist. If the host bridge is in the whitelist, return
6389d43745228d Logan Gunthorpe 2021-06-10 445 * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE with the distance set to the number of
6389d43745228d Logan Gunthorpe 2021-06-10 446 * ports per above. If the device is not in the whitelist, return
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 447 * PCI_P2PDMA_MAP_NOT_SUPPORTED.
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 448 */
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 449 static enum pci_p2pdma_map_type
6389d43745228d Logan Gunthorpe 2021-06-10 450 calc_map_type_and_dist(struct pci_dev *provider, struct pci_dev *client,
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 451 int *dist, bool verbose)
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 452 {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 453 enum pci_p2pdma_map_type map_type = PCI_P2PDMA_MAP_THRU_HOST_BRIDGE;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 454 struct pci_dev *a = provider, *b = client, *bb;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 455 bool acs_redirects = false;
ae21f835a5bda0 Eric Dumazet 2021-07-01 456 struct pci_p2pdma *p2pdma;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 457 struct seq_buf acs_list;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 458 int acs_cnt = 0;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 459 int dist_a = 0;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 460 int dist_b = 0;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 461 char buf[128];
e2cbfbf78968db Logan Gunthorpe 2019-08-12 462
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 463 seq_buf_init(&acs_list, buf, sizeof(buf));
e2cbfbf78968db Logan Gunthorpe 2019-08-12 464
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 465 /*
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 466 * Note, we don't need to take references to devices returned by
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 467 * pci_upstream_bridge() seeing we hold a reference to a child
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 468 * device which will already hold a reference to the upstream bridge.
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 469 */
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 470 while (a) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 471 dist_b = 0;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 472
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 473 if (pci_bridge_has_acs_redir(a)) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 474 seq_buf_print_bus_devfn(&acs_list, a);
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 475 acs_cnt++;
e2cbfbf78968db Logan Gunthorpe 2019-08-12 476 }
e2cbfbf78968db Logan Gunthorpe 2019-08-12 477
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 478 bb = b;
110203bee05f33 Logan Gunthorpe 2019-08-12 479
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 480 while (bb) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 481 if (a == bb)
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 482 goto check_b_path_acs;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 483
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 484 bb = pci_upstream_bridge(bb);
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 485 dist_b++;
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 486 }
c6bfaeb573a6ca Logan Gunthorpe 2019-08-12 487
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 488 a = pci_upstream_bridge(a);
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 489 dist_a++;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 490 }
52916982af48d9 Logan Gunthorpe 2018-10-04 491
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 492 *dist = dist_a + dist_b;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 493 goto map_through_host_bridge;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 494
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 495 check_b_path_acs:
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 496 bb = b;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 497
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 498 while (bb) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 499 if (a == bb)
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 500 break;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 501
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 502 if (pci_bridge_has_acs_redir(bb)) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 503 seq_buf_print_bus_devfn(&acs_list, bb);
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 504 acs_cnt++;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 505 }
52916982af48d9 Logan Gunthorpe 2018-10-04 506
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 507 bb = pci_upstream_bridge(bb);
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 508 }
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 509
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 510 *dist = dist_a + dist_b;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 511
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 512 if (!acs_cnt) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 513 map_type = PCI_P2PDMA_MAP_BUS_ADDR;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 514 goto done;
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 515 }
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 516
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 517 if (verbose) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 518 acs_list.buffer[acs_list.len-1] = 0; /* drop final semicolon */
72583084e3fe33 Logan Gunthorpe 2019-08-12 519 pci_warn(client, "ACS redirect is set between the client and provider (%s)\n",
52916982af48d9 Logan Gunthorpe 2018-10-04 520 pci_name(provider));
52916982af48d9 Logan Gunthorpe 2018-10-04 521 pci_warn(client, "to disable ACS redirect for this path, add the kernel parameter: pci=disable_acs_redir=%s\n",
52916982af48d9 Logan Gunthorpe 2018-10-04 522 acs_list.buffer);
72583084e3fe33 Logan Gunthorpe 2019-08-12 523 }
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 524 acs_redirects = true;
52916982af48d9 Logan Gunthorpe 2018-10-04 525
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 526 map_through_host_bridge:
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 527 if (!cpu_supports_p2pdma() &&
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 528 !host_bridge_whitelist(provider, client, acs_redirects)) {
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 529 if (verbose)
72583084e3fe33 Logan Gunthorpe 2019-08-12 530 pci_warn(client, "cannot be used for peer-to-peer DMA as the client and provider (%s) do not share an upstream bridge or whitelisted host bridge\n",
52916982af48d9 Logan Gunthorpe 2018-10-04 531 pci_name(provider));
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 532 map_type = PCI_P2PDMA_MAP_NOT_SUPPORTED;
52916982af48d9 Logan Gunthorpe 2018-10-04 533 }
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 534 done:
ae21f835a5bda0 Eric Dumazet 2021-07-01 535 rcu_read_lock();
ae21f835a5bda0 Eric Dumazet 2021-07-01 @536 p2pdma = rcu_dereference(provider->p2pdma);
ae21f835a5bda0 Eric Dumazet 2021-07-01 537 if (p2pdma)
ae21f835a5bda0 Eric Dumazet 2021-07-01 @538 xa_store(&p2pdma->map_types, map_types_idx(client),
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 539 xa_mk_value(map_type), GFP_KERNEL);
ae21f835a5bda0 Eric Dumazet 2021-07-01 540 rcu_read_unlock();
d1b8dc09dd7124 Christoph Hellwig 2021-06-14 541 return map_type;
52916982af48d9 Logan Gunthorpe 2018-10-04 542 }
52916982af48d9 Logan Gunthorpe 2018-10-04 543
:::::: The code at line 536 was first introduced by commit
:::::: ae21f835a5bda0ef1d00940373445693a764d89e PCI/P2PDMA: Finish RCU conversion of pdev->p2pdma
:::::: TO: Eric Dumazet <edumazet@google.com>
:::::: CC: Bjorn Helgaas <bhelgaas@google.com>
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-12-18 21:00 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-13 0:51 drivers/pci/p2pdma.c:536:11: warning: Dereference of null pointer [clang-analyzer-core.NullDereference] kernel test robot
-- strict thread matches above, loose matches on Subject: below --
2021-12-18 21:00 kernel test robot
2021-12-09 22:25 kernel test robot
2021-12-08 23:13 kernel test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.