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

Reply via email to