[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <201806290606.D0qKNdG9%fengguang.wu@intel.com>
Date: Fri, 29 Jun 2018 06:21:25 +0800
From: kbuild test robot <lkp@...el.com>
To: Roman Gushchin <guro@...com>
Cc: kbuild-all@...org, netdev@...r.kernel.org, kernel-team@...com,
tj@...nel.org, Roman Gushchin <guro@...com>,
Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>
Subject: Re: [PATCH bpf-net 05/14] bpf: extend bpf_prog_array to store
pointers to the cgroup storage
Hi Roman,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on bpf-next/master]
[also build test WARNING on v4.18-rc2]
[cannot apply to next-20180628]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Roman-Gushchin/bpf-cgroup-local-storage/20180629-035104
base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
reproduce:
# apt-get install sparse
make ARCH=x86_64 allmodconfig
make C=1 CF=-D__CHECK_ENDIAN__
sparse warnings: (new ones prefixed by >>)
include/linux/filter.h:632:16: sparse: expression using sizeof(void)
kernel/bpf/core.c:603:16: sparse: expression using sizeof(void)
kernel/bpf/core.c:1572:31: sparse: incorrect type in return expression (different address spaces) @@ expected struct bpf_prog_array [noderef] <asn:4>* @@ got sn:4>* @@
kernel/bpf/core.c:1572:31: expected struct bpf_prog_array [noderef] <asn:4>*
kernel/bpf/core.c:1572:31: got void *
kernel/bpf/core.c:1577:17: sparse: incorrect type in return expression (different address spaces) @@ expected struct bpf_prog_array [noderef] <asn:4>* @@ got rray [noderef] <asn:4>* @@
kernel/bpf/core.c:1577:17: expected struct bpf_prog_array [noderef] <asn:4>*
kernel/bpf/core.c:1577:17: got struct bpf_prog_array *<noident>
kernel/bpf/core.c:1585:9: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct callback_head *head @@ got struct callback_hstruct callback_head *head @@
kernel/bpf/core.c:1585:9: expected struct callback_head *head
kernel/bpf/core.c:1585:9: got struct callback_head [noderef] <asn:4>*<noident>
>> kernel/bpf/core.c:1610:16: sparse: incompatible types in comparison expression (different address spaces)
include/linux/slab.h:631:13: sparse: undefined identifier '__builtin_mul_overflow'
>> kernel/bpf/core.c:1659:44: sparse: incorrect type in initializer (different address spaces) @@ expected struct bpf_prog_array_item *item @@ got struct bpf_prog_astruct bpf_prog_array_item *item @@
>> kernel/bpf/core.c:1683:26: sparse: incorrect type in assignment (different address spaces) @@ expected struct bpf_prog_array_item *existing @@ got struct bpf_prog_astruct bpf_prog_array_item *existing @@
kernel/bpf/core.c:1711:15: sparse: incorrect type in assignment (different address spaces) @@ expected struct bpf_prog_array *array @@ got struct bpf_prog_astruct bpf_prog_array *array @@
>> kernel/bpf/core.c:1717:26: sparse: incorrect type in assignment (different address spaces) @@ expected struct bpf_prog_array_item *[assigned] existing @@ got structstruct bpf_prog_array_item *[assigned] existing @@
>> kernel/bpf/core.c:1748:41: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct bpf_prog_array *[addressable] array @@ got strstruct bpf_prog_array *[addressable] array @@
include/trace/events/xdp.h:28:1: sparse: Using plain integer as NULL pointer
include/trace/events/xdp.h:53:1: sparse: Using plain integer as NULL pointer
include/trace/events/xdp.h:111:1: sparse: Using plain integer as NULL pointer
include/trace/events/xdp.h:126:1: sparse: Using plain integer as NULL pointer
include/trace/events/xdp.h:162:1: sparse: Using plain integer as NULL pointer
include/trace/events/xdp.h:197:1: sparse: Using plain integer as NULL pointer
include/trace/events/xdp.h:232:1: sparse: Using plain integer as NULL pointer
kernel/bpf/core.c:950:18: sparse: Initializer entry defined twice
include/linux/slab.h:631:13: sparse: call with no type!
vim +1610 kernel/bpf/core.c
1568
1569 struct bpf_prog_array __rcu *bpf_prog_array_alloc(u32 prog_cnt, gfp_t flags)
1570 {
1571 if (prog_cnt)
> 1572 return kzalloc(sizeof(struct bpf_prog_array) +
1573 sizeof(struct bpf_prog_array_item) *
1574 (prog_cnt + 1),
1575 flags);
1576
> 1577 return &empty_prog_array.hdr;
1578 }
1579
1580 void bpf_prog_array_free(struct bpf_prog_array __rcu *progs)
1581 {
1582 if (!progs ||
1583 progs == (struct bpf_prog_array __rcu *)&empty_prog_array.hdr)
1584 return;
> 1585 kfree_rcu(progs, rcu);
1586 }
1587
1588 int bpf_prog_array_length(struct bpf_prog_array __rcu *array)
1589 {
1590 struct bpf_prog_array_item *item;
1591 u32 cnt = 0;
1592
1593 rcu_read_lock();
1594 item = rcu_dereference(array)->items;
1595 for (; item->prog; item++)
1596 if (item->prog != &dummy_bpf_prog.prog)
1597 cnt++;
1598 rcu_read_unlock();
1599 return cnt;
1600 }
1601
1602
1603 static bool bpf_prog_array_copy_core(struct bpf_prog_array *array,
1604 u32 *prog_ids,
1605 u32 request_cnt)
1606 {
1607 struct bpf_prog_array_item *item;
1608 int i = 0;
1609
> 1610 item = rcu_dereference(array)->items;
1611 for (; item->prog; item++) {
1612 if (item->prog == &dummy_bpf_prog.prog)
1613 continue;
1614 prog_ids[i] = item->prog->aux->id;
1615 if (++i == request_cnt) {
1616 item++;
1617 break;
1618 }
1619 }
1620
1621 return !!(item->prog);
1622 }
1623
1624 int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *array,
1625 __u32 __user *prog_ids, u32 cnt)
1626 {
1627 unsigned long err = 0;
1628 bool nospc;
1629 u32 *ids;
1630
1631 /* users of this function are doing:
1632 * cnt = bpf_prog_array_length();
1633 * if (cnt > 0)
1634 * bpf_prog_array_copy_to_user(..., cnt);
1635 * so below kcalloc doesn't need extra cnt > 0 check, but
1636 * bpf_prog_array_length() releases rcu lock and
1637 * prog array could have been swapped with empty or larger array,
1638 * so always copy 'cnt' prog_ids to the user.
1639 * In a rare race the user will see zero prog_ids
1640 */
1641 ids = kcalloc(cnt, sizeof(u32), GFP_USER | __GFP_NOWARN);
1642 if (!ids)
1643 return -ENOMEM;
1644 rcu_read_lock();
1645 nospc = bpf_prog_array_copy_core(array, ids, cnt);
1646 rcu_read_unlock();
1647 err = copy_to_user(prog_ids, ids, cnt * sizeof(u32));
1648 kfree(ids);
1649 if (err)
1650 return -EFAULT;
1651 if (nospc)
1652 return -ENOSPC;
1653 return 0;
1654 }
1655
1656 void bpf_prog_array_delete_safe(struct bpf_prog_array __rcu *array,
1657 struct bpf_prog *old_prog)
1658 {
> 1659 struct bpf_prog_array_item *item = array->items;
1660
1661 for (; item->prog; item++)
1662 if (item->prog == old_prog) {
1663 WRITE_ONCE(item->prog, &dummy_bpf_prog.prog);
1664 break;
1665 }
1666 }
1667
1668 int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,
1669 struct bpf_prog *exclude_prog,
1670 struct bpf_prog *include_prog,
1671 struct bpf_prog_array **new_array)
1672 {
1673 int new_prog_cnt, carry_prog_cnt = 0;
1674 struct bpf_prog_array_item *existing;
1675 struct bpf_prog_array *array;
1676 bool found_exclude = false;
1677 int new_prog_idx = 0;
1678
1679 /* Figure out how many existing progs we need to carry over to
1680 * the new array.
1681 */
1682 if (old_array) {
> 1683 existing = old_array->items;
1684 for (; existing->prog; existing++) {
1685 if (existing->prog == exclude_prog) {
1686 found_exclude = true;
1687 continue;
1688 }
1689 if (existing->prog != &dummy_bpf_prog.prog)
1690 carry_prog_cnt++;
1691 if (existing->prog == include_prog)
1692 return -EEXIST;
1693 }
1694 }
1695
1696 if (exclude_prog && !found_exclude)
1697 return -ENOENT;
1698
1699 /* How many progs (not NULL) will be in the new array? */
1700 new_prog_cnt = carry_prog_cnt;
1701 if (include_prog)
1702 new_prog_cnt += 1;
1703
1704 /* Do we have any prog (not NULL) in the new array? */
1705 if (!new_prog_cnt) {
1706 *new_array = NULL;
1707 return 0;
1708 }
1709
1710 /* +1 as the end of prog_array is marked with NULL */
1711 array = bpf_prog_array_alloc(new_prog_cnt + 1, GFP_KERNEL);
1712 if (!array)
1713 return -ENOMEM;
1714
1715 /* Fill in the new prog array */
1716 if (carry_prog_cnt) {
> 1717 existing = old_array->items;
1718 for (; existing->prog; existing++)
1719 if (existing->prog != exclude_prog &&
1720 existing->prog != &dummy_bpf_prog.prog) {
1721 array->items[new_prog_idx++].prog =
1722 existing->prog;
1723 }
1724 }
1725 if (include_prog)
1726 array->items[new_prog_idx++].prog = include_prog;
1727 array->items[new_prog_idx].prog = NULL;
1728 *new_array = array;
1729 return 0;
1730 }
1731
1732 int bpf_prog_array_copy_info(struct bpf_prog_array __rcu *array,
1733 u32 *prog_ids, u32 request_cnt,
1734 u32 *prog_cnt)
1735 {
1736 u32 cnt = 0;
1737
1738 if (array)
1739 cnt = bpf_prog_array_length(array);
1740
1741 *prog_cnt = cnt;
1742
1743 /* return early if user requested only program count or nothing to copy */
1744 if (!request_cnt || !cnt)
1745 return 0;
1746
1747 /* this function is called under trace/bpf_trace.c: bpf_event_mutex */
> 1748 return bpf_prog_array_copy_core(array, prog_ids, request_cnt) ? -ENOSPC
1749 : 0;
1750 }
1751
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
Powered by blists - more mailing lists