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