[PATCH V8 1/6] LIBIO: Introduce a generic PIO mapping method

kbuild test robot lkp at intel.com
Fri Mar 31 22:58:10 PDT 2017


Hi zhichang.yuan,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.11-rc4 next-20170331]
[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/zhichang-yuan/LIBIO-Introduce-a-generic-PIO-mapping-method/20170401-104801
config: alpha-allyesconfig (attached as .config)
compiler: alpha-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=alpha 

All error/warnings (new ones prefixed by >>):

>> lib/logic_pio.c:32:50: error: 'PIO_MAX_SECT' undeclared here (not in a function)
    static struct logic_pio_root logic_pio_root_list[PIO_MAX_SECT] = {
                                                     ^~~~~~~~~~~~
>> lib/logic_pio.c:39:3: error: 'PIO_CPU_MMIO' undeclared here (not in a function)
     [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
      ^~~~~~~~~~~~
>> lib/logic_pio.c:39:20: error: 'PIO_INDIRECT' undeclared here (not in a function)
     [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
                       ^~~~~~~~~~~~
>> lib/logic_pio.c:39:3: error: array index in initializer not of integer type
     [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
      ^~~~~~~~~~~~
   lib/logic_pio.c:39:3: note: (near initialization for 'logic_pio_root_list')
>> lib/logic_pio.c:40:3: error: field name not in record or union initializer
      .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
      ^
   lib/logic_pio.c:40:3: note: (near initialization for 'logic_pio_root_list')
   lib/logic_pio.c:41:3: error: field name not in record or union initializer
      .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
      ^
   lib/logic_pio.c:41:3: note: (near initialization for 'logic_pio_root_list')
>> lib/logic_pio.c:41:14: error: implicit declaration of function 'PIO_SECT_MIN' [-Werror=implicit-function-declaration]
      .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
                 ^~~~~~~~~~~~
   lib/logic_pio.c:42:3: error: field name not in record or union initializer
      .sec_max = PIO_SECT_MAX(PIO_INDIRECT - 1),
      ^
   lib/logic_pio.c:42:3: note: (near initialization for 'logic_pio_root_list')
>> lib/logic_pio.c:42:14: error: implicit declaration of function 'PIO_SECT_MAX' [-Werror=implicit-function-declaration]
      .sec_max = PIO_SECT_MAX(PIO_INDIRECT - 1),
                 ^~~~~~~~~~~~
   lib/logic_pio.c:46:3: error: array index in initializer not of integer type
     [PIO_INDIRECT] = {
      ^~~~~~~~~~~~
   lib/logic_pio.c:46:3: note: (near initialization for 'logic_pio_root_list')
   lib/logic_pio.c:47:3: error: field name not in record or union initializer
      .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_INDIRECT].sec_head),
      ^
   lib/logic_pio.c:47:3: note: (near initialization for 'logic_pio_root_list')
   lib/logic_pio.c:48:3: error: field name not in record or union initializer
      .sec_min = PIO_SECT_MIN(PIO_INDIRECT),
      ^
   lib/logic_pio.c:48:3: note: (near initialization for 'logic_pio_root_list')
   lib/logic_pio.c:49:3: error: field name not in record or union initializer
      .sec_max = PIO_SECT_MAX(PIO_INDIRECT),
      ^
   lib/logic_pio.c:49:3: note: (near initialization for 'logic_pio_root_list')
   In file included from include/linux/list.h:8:0,
                    from include/linux/kobject.h:20,
                    from include/linux/of.h:21,
                    from lib/logic_pio.c:18:
   lib/logic_pio.c: In function 'logic_pio_find_range_byaddr':
>> include/linux/rculist.h:351:49: error: dereferencing pointer to incomplete type 'struct logic_pio_hwaddr'
     for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
                                                     
   include/linux/kernel.h:852:18: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                     ^~~~
>> include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
     for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
                ^~~~~~~~~~~~~~
>> lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
     list_for_each_entry_rcu(range, &io_range_list, list) {
     ^~~~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
>> include/linux/rculist.h:277:2: note: in expansion of macro 'container_of'
     container_of(lockless_dereference(ptr), type, member)
     ^~~~~~~~~~~~
>> include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
     for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
                ^~~~~~~~~~~~~~
>> lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
     list_for_each_entry_rcu(range, &io_range_list, list) {
     ^~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/kernel.h:852:48: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^
>> include/linux/rculist.h:277:2: note: in expansion of macro 'container_of'
     container_of(lockless_dereference(ptr), type, member)
     ^~~~~~~~~~~~
   include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
      pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
            ^~~~~~~~~~~~~~
>> lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
     list_for_each_entry_rcu(range, &io_range_list, list) {
     ^~~~~~~~~~~~~~~~~~~~~~~
   lib/logic_pio.c: In function 'logic_pio_alloc_range':
>> lib/logic_pio.c:109:19: error: dereferencing pointer to incomplete type 'struct logic_pio_root'
     idle_start = root->sec_min;
                      ^~
   In file included from include/linux/list.h:8:0,
                    from include/linux/kobject.h:20,
                    from include/linux/of.h:21,
                    from lib/logic_pio.c:18:
>> include/linux/rculist.h:351:49: error: dereferencing pointer to incomplete type 'struct logic_pio_sect'
     for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
                                                     
   include/linux/kernel.h:852:18: note: in definition of macro 'container_of'
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                     ^~~~
>> include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
     for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
                ^~~~~~~~~~~~~~
   lib/logic_pio.c:111:2: note: in expansion of macro 'list_for_each_entry_rcu'
     list_for_each_entry_rcu(entry, &root->sec_head, list) {
     ^~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/kernel.h:852:48: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
     const typeof( ((type *)0)->member ) *__mptr = (ptr); \
                                                   ^

vim +/PIO_MAX_SECT +32 lib/logic_pio.c

    12	 * GNU General Public License for more details.
    13	 *
    14	 * You should have received a copy of the GNU General Public License
    15	 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16	 */
    17	
  > 18	#include <linux/of.h>
    19	#include <linux/io.h>
    20	#include <linux/mm.h>
    21	#include <linux/rculist.h>
    22	#include <linux/sizes.h>
    23	#include <linux/slab.h>
    24	
    25	/* The unique hardware address list. */
    26	static LIST_HEAD(io_range_list);
    27	static DEFINE_MUTEX(io_range_mutex);
    28	
    29	/*
    30	 * These are the lists for PIO. The highest PIO_SECT_BITS of PIO is the index.
    31	 */
  > 32	static struct logic_pio_root logic_pio_root_list[PIO_MAX_SECT] = {
    33	#ifdef CONFIG_INDIRECT_PIO
    34		/*
    35		 * At this moment, assign all the other logic PIO space to MMIO.
    36		 * If more elements added, please adjust the ending index and .sec_max;
    37		 * Please keep MMIO element started from index ZERO.
    38		 */
  > 39		[PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
  > 40			.sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
  > 41			.sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
  > 42			.sec_max = PIO_SECT_MAX(PIO_INDIRECT - 1),
    43		},
    44	
    45		/* The last element */
    46		[PIO_INDIRECT] = {
    47			.sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_INDIRECT].sec_head),
    48			.sec_min = PIO_SECT_MIN(PIO_INDIRECT),
    49			.sec_max = PIO_SECT_MAX(PIO_INDIRECT),
    50		},
    51	#else
    52		[PIO_CPU_MMIO] = {
    53			.sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
    54			.sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
    55			.sec_max = PIO_SECT_MAX(PIO_CPU_MMIO),
    56		},
    57	
    58	#endif
    59	};
    60	
    61	/*
    62	 * Search a io_range registered which match the fwnode and addr.
    63	 *
    64	 * @fwnode: the host fwnode which must be valid;
    65	 * @start: the start hardware address of this search;
    66	 * @end: the end hardware address of this search. can be equal to @start;
    67	 *
    68	 * return NULL when there is no matched node; IS_ERR() means ERROR;
    69	 * valid virtual address represent a matched node was found.
    70	 */
    71	static struct logic_pio_hwaddr *
    72	logic_pio_find_range_byaddr(struct fwnode_handle *fwnode,
    73				resource_size_t start, resource_size_t end)
    74	{
    75		struct logic_pio_hwaddr *range;
    76	
  > 77		list_for_each_entry_rcu(range, &io_range_list, list) {
    78			if (!range->pio_peer) {
    79				pr_warn("Invalid cpu addr node(%pa) in list!\n",
    80					&range->hw_start);
    81				continue;
    82			}
    83			if (range->fwnode != fwnode)
    84				continue;
    85			/* without any overlap with current range */
    86			if (start >= range->hw_start + range->size ||
    87				end < range->hw_start)
    88				continue;
    89			/* overlap is not supported now. */
    90			if (start < range->hw_start ||
    91				end >= range->hw_start + range->size)
    92				return ERR_PTR(-EBUSY);
    93			/* had been registered. */
    94			return range;
    95		}
    96	
    97		return NULL;
    98	}
    99	
   100	
   101	static int logic_pio_alloc_range(struct logic_pio_root *root,
   102			resource_size_t size, unsigned long align,
   103			struct list_head **prev, resource_size_t *pio_alloc)
   104	{
   105		struct logic_pio_sect *entry;
   106		resource_size_t tmp_start;
   107		resource_size_t idle_start, idle_end;
   108	
 > 109		idle_start = root->sec_min;
   110		*prev = &root->sec_head;
   111		list_for_each_entry_rcu(entry, &root->sec_head, list) {
   112			if (!entry->hwpeer ||
   113				idle_start > entry->io_start) {
   114				WARN(1, "skip an invalid io range during traversal!\n");
   115				goto nextentry;
   116			}
   117			/* set the end edge. */
   118			if (idle_start == entry->io_start) {
   119				struct logic_pio_sect *next;
   120	
   121				idle_start = entry->io_start + entry->hwpeer->size;
 > 122				next = list_next_or_null_rcu(&root->sec_head,
 > 123					&entry->list, struct logic_pio_sect, list);
   124				if (next) {
   125					entry = next;
   126				} else {
   127					*prev = &entry->list;
   128					break;
   129				}
   130			}
   131			idle_end = entry->io_start - 1;
   132	
   133			/* contiguous range... */
   134			if (idle_start > idle_end)
   135				goto nextentry;
   136	
   137			tmp_start = idle_start;
   138			idle_start = ALIGN(idle_start, align);
   139			if (idle_start >= tmp_start &&
   140				idle_start + size <= idle_end) {
   141				*prev = &entry->list;
   142				*pio_alloc = idle_start;
   143				return 0;
   144			}
   145	
   146	nextentry:
   147			idle_start = entry->io_start + entry->hwpeer->size;
   148			*prev = &entry->list;
   149		}
   150		/* check the last free gap... */
   151		idle_end = root->sec_max;
   152	
   153		tmp_start = idle_start;
   154		idle_start = ALIGN(idle_start, align);
   155		if (idle_start >= tmp_start &&
   156			idle_start + size <= idle_end) {
   157			*pio_alloc = idle_start;
   158			return 0;
   159		}
   160	
   161		return -EBUSY;
   162	}
   163	
   164	/*
   165	 * register a io range node in the io range list.
   166	 *
   167	 * @newrange: pointer to the io range to be registered.
   168	 *
   169	 * return 'newrange' when success, ERR_VALUE() is for failures.
   170	 * specially, return a valid pointer which is not equal to 'newrange' when
   171	 * the io range had been registered before.
   172	 */
   173	struct logic_pio_hwaddr
   174	*logic_pio_register_range(struct logic_pio_hwaddr *newrange,
   175			unsigned long align)
   176	{
   177		struct logic_pio_hwaddr *range;
   178		struct logic_pio_sect *newsect;
   179		resource_size_t pio_alloc;
   180		struct list_head *prev, *hwprev;
   181		unsigned long sect_id;
   182		int err;
   183	
   184		if (!newrange || !newrange->fwnode || !newrange->size)
   185			return ERR_PTR(-EINVAL);
   186	
   187		sect_id = newrange->flags;
   188		if (sect_id >= PIO_MAX_SECT)
   189			return ERR_PTR(-EINVAL);
   190	
   191		mutex_lock(&io_range_mutex);
   192		range = logic_pio_find_range_byaddr(newrange->fwnode,
   193				newrange->hw_start,
   194				newrange->hw_start + newrange->size - 1);
   195		if (range) {
   196			if (!IS_ERR(range))
   197				pr_info("the request IO range had been registered!\n");
   198			else
   199				pr_err("registering IO[%pa - sz%pa) got failed!\n",
   200					&newrange->hw_start, &newrange->size);
   201			mutex_unlock(&io_range_mutex);
   202			return range;
   203		}
   204	
   205		err = logic_pio_alloc_range(&logic_pio_root_list[sect_id],
   206				newrange->size, align, &prev, &pio_alloc);
   207		if (err) {
   208			pr_err("can't find free %pa logical IO range!\n",
   209				&newrange->size);
   210			goto exitproc;
   211		}
   212	
   213		if (prev == &logic_pio_root_list[sect_id].sec_head) {
   214			hwprev = &io_range_list;
   215		} else {
 > 216			newsect = to_pio_sect(prev);
 > 217			hwprev = &newsect->hwpeer->list;
   218		}
   219	
   220		newsect = kzalloc(sizeof(*newsect), GFP_KERNEL);

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 49584 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170401/a8a24a37/attachment-0001.gz>


More information about the linux-arm-kernel mailing list