On Fri, Nov 14, 2014 at 10:48:21AM +0000, Bruce Richardson wrote: > On Wed, Nov 12, 2014 at 03:22:37AM +0000, Chi, Xiaobo (NSN - CN/Hangzhou) > wrote: > > Hi, > > Background: > > What we are doing now is port make telecom network element to be cloud > > based. For one of our product, DPDK is applied not only for > > fastpath/dataplane processing, but also for Distributed Message eXchange > > (DMX) between different processes/applications which may located in > > different VM even different host. for such a DMX system, in one VM, we > > have one DPDK based dmxdemo (which acts as the PRIMARY) which is in charge > > of distribute message between different applications, and dozens of > > applications (act as SECONDARY) to use DPDK based > > rte_tx_ring/rte_rx_ring/mempool/memzone to send receive messages to dmxdemo. > > > > Problem: > > Here, these DPDK based SECONDARY processes need only the DPDK's hugepage > > based sharememory mechanism and it's upper libs (such as ring, mempool, > > etc.), they need not cpu core pinning, iopl privilege changing , pci > > device, timer, alarm, interrupt, shared_driver_list, core_info, threads > > for each core, etc. Then, for such kind of SECONDARY processes, the current > > rte_eal_init() is too heavy. > > I have seen some others also met similar troubles. > > > > Solution: > > I write one light weight rte_eal_init(), called > > rte_eal_secondary_mem_init() as following. It only initializes shared > > memory and mandatory resources. I expect your review and hope these code > > can be merged into DPDK main branch. > > > > Rather than writing a whole new API and arg parsing function, might it be > better > to implement this just as an additional EAL flag that prevents the existing > eal_init function from doing all tasks? > > /Bruce > +1, that seems like a more compatible approach. Neil
> > > static void eal_secondary_mem_parse_args(int argc, char **argv) > > { > > static struct option lgopts[] = { > > {OPT_HUGE_DIR, 1, 0, 0}, > > {OPT_FILE_PREFIX, 1, 0, 0}, > > {0, 0, 0, 0} > > }; > > > > int opt; > > int option_index; > > > > while ((opt = getopt_long(argc, argv, "", lgopts, &option_index)) > > != EOF) { > > > > if (!opt ) { > > if (!strcmp(lgopts[option_index].name, OPT_HUGE_DIR)) { > > internal_config.hugepage_dir = optarg; > > } > > else if (!strcmp(lgopts[option_index].name, OPT_FILE_PREFIX)) { > > internal_config.hugefile_prefix = optarg; > > } > > } > > } > > } > > > > int rte_eal_secondary_mem_init( int argc, char **argv ) > > { > > static rte_atomic32_t run_once = RTE_ATOMIC32_INIT(0); > > const char *logid; > > > > if (!rte_atomic32_test_and_set(&run_once)) > > return -1; > > > > logid = strrchr(argv[0], '/'); > > logid = strdup(logid ? logid + 1: argv[0]); > > > > if (rte_eal_log_early_init() < 0) > > rte_panic("Cannot init early logs\n"); > > > > memset( &internal_config, 0, sizeof( struct internal_config ) ); > > /*this is only for secondary PRBs */ > > internal_config.process_type = RTE_PROC_SECONDARY; > > internal_config.hugefile_prefix = HUGEFILE_PREFIX_DEFAULT; > > internal_config.hugepage_dir = NULL; > > /* user can freely define the hugefile_prefix and hugepage_dir */ > > eal_secondary_mem_parse_args( argc, argv ); > > > > RTE_LOG(INFO, EAL, "prefix=%s, > > dir=%s.\n",internal_config.hugefile_prefix, internal_config.hugepage_dir ); > > > > /* To share memory config with PRIMARY process */ > > internal_config.no_shconf = 0; > > rte_config_init(); > > > > if (rte_eal_memory_init() < 0) > > rte_panic("Cannot init memory\n"); > > > > if (rte_eal_memzone_init() < 0) > > rte_panic("Cannot init memzone\n"); > > > > if (rte_eal_log_init(logid, LOG_DAEMON ) < 0) > > rte_panic("Cannot init logs\n"); > > > > return 0; > > } > > > > brgs, > > chi xiaobo > > > > > > >