> [Bhanu Prakash Gollapudi wrote:] > > On 2/23/2012 10:08 AM, Clark, Steven wrote: > > > I am seeing a failure in fcoe_transport_create on a 64-bit single-CPU > > > environment (I'm testing in a VM with one CPU > > assigned). > > > The size in the call to __alloc_percpu() is greater than the max of 32K > > > because it allocates 4K pointers + header across all > > CPUs. > > > Reducing FCOE_MAX_ID from 0x0FFF to 0x0F7F fixes the problem at the > > > expense of 0x80 fewer allowed open > > exchanges. > > > I can prepare a patch for that, but maybe someone knowledgeable can > > > suggest a better fix. > > > > One way to fix is to use smaller XID range based on nr_cpu_ids. > > > > Looks like FCP should be seeing this same issue since it also allocates 4K > exchanges: > #define FCPIO_HOST_EXCH_RANGE_START 0x1000 > #define FCPIO_HOST_EXCH_RANGE_END 0x1fff > > So the right way to fix is what you suggest. > fc_exch_mgr_alloc is already adjusting the allocation based on the number of > cpus so can do this > as a special case. I'll try that out and prepare a patch. > >
My colleague Vlad Senkov suggested a more general way to solve the issue than making single CPU a special case. I verified that this gives the original allocation on multi-CPU and reduces the allocation from 4096 to 4088 on the problem single CPU case. --- orig/drivers/scsi/libfc/fc_exch.c 2012-02-24 11:22:32.242157149 -0500 +++ fcoe-next/drivers/scsi/libfc/fc_exch.c 2012-02-24 15:14:35.033962311 -0500 @@ -2284,8 +2284,19 @@ mp->class = class; /* adjust em exch xid range for offload */ mp->min_xid = min_xid; - mp->max_xid = max_xid; + /* reduce range so per cpu pool fits into PCPU_MIN_UNIT_SIZE pool */ + pool_exch_range = (PCPU_MIN_UNIT_SIZE - sizeof(*pool)) / + sizeof(struct fc_exch *); + if ((max_xid - min_xid + 1) / (fc_cpu_mask + 1) > pool_exch_range) { + mp->max_xid = pool_exch_range * (fc_cpu_mask + 1) + + min_xid - 1; + } else { + mp->max_xid = max_xid; + pool_exch_range = (mp->max_xid - mp->min_xid + 1) / + (fc_cpu_mask + 1); + } + mp->ep_pool = mempool_create_slab_pool(2, fc_em_cachep); if (!mp->ep_pool) goto free_mp; @@ -2295,7 +2306,6 @@ * divided across all cpus. The exch pointers array memory is * allocated for exch range per pool. */ - pool_exch_range = (mp->max_xid - mp->min_xid + 1) / (fc_cpu_mask + 1); mp->pool_max_index = pool_exch_range - 1; /* _______________________________________________ devel mailing list devel@open-fcoe.org https://lists.open-fcoe.org/mailman/listinfo/devel