From owner-p4-projects@FreeBSD.ORG Fri Jul 2 11:27:45 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id DB6BA1065674; Fri, 2 Jul 2010 11:27:44 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9DFDB1065670 for ; Fri, 2 Jul 2010 11:27:44 +0000 (UTC) (envelope-from afiveg@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 8A6928FC1C for ; Fri, 2 Jul 2010 11:27:44 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o62BRi2D093295 for ; Fri, 2 Jul 2010 11:27:44 GMT (envelope-from afiveg@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o62BRi4i093293 for perforce@freebsd.org; Fri, 2 Jul 2010 11:27:44 GMT (envelope-from afiveg@FreeBSD.org) Date: Fri, 2 Jul 2010 11:27:44 GMT Message-Id: <201007021127.o62BRi4i093293@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to afiveg@FreeBSD.org using -f From: Alexandre Fiveg To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 180408 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 02 Jul 2010 11:27:45 -0000 http://p4web.freebsd.org/@@180408?ac=10 Change 180408 by afiveg@cottonmouth on 2010/07/02 11:26:58 New synchronizations features: now we a re using ringmap mutexes defined in the ringmap structure. Affected files ... .. //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap-bpf.c#4 edit .. //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap-int.h#4 edit .. //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap.c#6 edit .. //depot/projects/soc2010/ringmap/current/contrib/libpcap/ringmap_pcap.c#11 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_80003es2lan.c#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_80003es2lan.h#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82540.c#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82541.c#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82541.h#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82542.c#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82543.c#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82543.h#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82571.c#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82571.h#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82575.c#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82575.h#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_api.c#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_api.h#5 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_defines.h#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_hw.h#7 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_ich8lan.c#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_ich8lan.h#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_mac.c#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_mac.h#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_manage.c#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_manage.h#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_nvm.c#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_nvm.h#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_osdep.c#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_osdep.h#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_phy.c#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_phy.h#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_regs.h#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_em.c#8 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_em.h#6 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_igb.c#6 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_igb.h#4 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_lem.c#19 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_lem.h#17 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_8254.c#18 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_8254.h#16 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_e1000.h#8 edit .. //depot/projects/soc2010/ringmap/current/sys/net/ringmap.c#22 edit .. //depot/projects/soc2010/ringmap/current/sys/net/ringmap.h#22 edit .. //depot/projects/soc2010/ringmap/scripts/build_ringmap.sh#6 edit .. //depot/projects/soc2010/ringmap/scripts/set_ringmap.sh#7 edit .. //depot/projects/soc2010/ringmap/scripts/tailf_ringmap_msgs.sh#2 edit Differences ... ==== //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap-bpf.c#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap-int.h#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap.c#6 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/contrib/libpcap/ringmap_pcap.c#11 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_80003es2lan.c#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_80003es2lan.h#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82540.c#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82541.c#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82541.h#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82542.c#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82543.c#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82543.h#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82571.c#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82571.h#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82575.c#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_82575.h#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_api.c#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_api.h#5 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_defines.h#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_hw.h#7 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_ich8lan.c#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_ich8lan.h#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_mac.c#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_mac.h#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_manage.c#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_manage.h#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_nvm.c#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_nvm.h#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_osdep.c#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_osdep.h#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_phy.c#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_phy.h#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/e1000_regs.h#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_em.c#8 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_em.h#6 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_igb.c#6 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_igb.h#4 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_lem.c#19 (text+ko) ==== @@ -1383,17 +1383,15 @@ if (ifp->if_drv_flags & IFF_DRV_RUNNING) { #ifdef RINGMAP - if ((adapter->rm != NULL) && (adapter->rm->ring != NULL)) + if (adapter->rm != NULL) { adapter->rm->funcs->delayed_isr(context); #endif if (lem_rxeof(adapter, adapter->rx_process_limit) != 0) taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); - #ifdef RINGMAP - if ((adapter->rm != NULL) && (adapter->rm->ring != NULL)) { adapter->rm->funcs->sync_head(adapter->dev, adapter->rm->ring); - if (adapter->rm != NULL) - wakeup(adapter->rm); + + wakeup(adapter->rm); } #endif @@ -1447,12 +1445,7 @@ lem_disable_intr(adapter); #ifdef RINGMAP - if ((adapter->rm != NULL) && /* ringmap structure should be allocated */ - (adapter->rm->ring != NULL) && - (adapter->rm->ring->td != NULL)) - { - adapter->rm->funcs->isr(arg); - } + adapter->rm->funcs->isr(arg); #endif taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); @@ -3581,12 +3574,14 @@ if (accept_frame) { #ifdef RINGMAP - if ((adapter->rm != NULL) && (adapter->rm->ring != NULL)) { + if (adapter->rm != NULL) { + RINGMAP_LOCK(adapter->rm); adapter->rm->funcs->delayed_isr_per_packet(adapter->rm->ring, i); #ifdef __RINGMAP_DEB PRINT_SLOT((adapter->rm->ring), (i), (adapter)); #endif + RINGMAP_UNLOCK(adapter->rm); } #endif ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_lem.h#17 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_8254.c#18 (text+ko) ==== @@ -25,7 +25,6 @@ void rm_8254_enable_intr(device_t); void rm_8254_disable_intr(device_t); int rm_8254_set_slot(struct ring *, struct adapter *, unsigned int); -void rm_8254_print_slot(struct ring *, unsigned int); void rm_8254_interrupt(void *); void rm_8254_delayed_interrupt(void *); int rm_8254_print_ring_pointers(struct adapter *); @@ -34,47 +33,19 @@ void rm_8254_sync_head(device_t, struct ring *); void rm_8254_delayed_interrupt_per_packet(struct ring *, int); struct ring *rm_8254_alloc_ring(device_t); -void rm_8254_free_ring(device_t, struct ring *); extern devclass_t em_devclass; extern void lem_enable_intr(struct adapter *); extern void lem_disable_intr(struct adapter *); +extern void ringmap_print_slot(struct ring *, unsigned int); -void -rm_8254_free_ring(device_t dev, struct ring *ring) -{ - struct adapter *adapter = (struct adapter *)device_get_softc(dev); - - if ( (adapter == NULL) || (ring == NULL) ) - goto out; - - /* Disable interrupts of adapter */ - rm_8254_disable_intr(dev); - - EM_RX_LOCK(adapter); - - contigfree(ring, sizeof(struct ring), M_DEVBUF); - - adapter->rm->ring = NULL; - - EM_RX_UNLOCK(adapter); - -out: ; - -} - struct ring * rm_8254_alloc_ring(device_t dev) { struct ring *ring; - struct adapter *adapter = (struct adapter *)device_get_softc(dev); - if ( (adapter == NULL) || (adapter->rm == NULL) ) { - return (NULL); - } - /* * Allocate memory for ring structure * Use contigmalloc(9) to get PAGE_SIZE alignment that is needed @@ -88,45 +59,14 @@ return (NULL); } - /* Disable interrupts of adapter while allocating the ring */ - rm_8254_disable_intr(dev); - EM_RX_LOCK(adapter); - - /* Set ring fields in the initial state */ - ring->kern_wait_user = 0; - ring->user_wait_kern = 0; - ring->interrupts_counter = 0; - ring->pkt_counter = 0; - ring->size = SLOTS_NUMBER; if (rm_8254_init_slots(ring, dev) == -1) { RINGMAP_ERROR(The ring is not initialized. Device will not be opened!); contigfree(ring, sizeof(struct ring), M_DEVBUF); - EM_RX_UNLOCK(adapter); - rm_8254_enable_intr(dev); - return (NULL); } - - /** - ** Currently only one process only one time can open our device !!! - **/ - if (!atomic_cmpset_int(&adapter->rm->open_cnt, 0, 1)){ - RINGMAP_ERROR(Sorry! Can not open device more then one time!); - atomic_readandclear_int(&adapter->rm->open_cnt); - - EM_RX_UNLOCK(adapter); - rm_8254_enable_intr(dev); - - return (NULL); - } - adapter->rm->ring = ring; - - EM_RX_UNLOCK(adapter); - rm_8254_enable_intr(dev); - return (ring); } @@ -141,8 +81,7 @@ ring->slot[slot_num].intr_num = ring->interrupts_counter; #ifdef RINGMAP_TIMESTAMP - ring->slot[slot_num].ts.tv_sec = ring->last_ts.tv_sec; - ring->slot[slot_num].ts.tv_usec = ring->last_ts.tv_usec; + ring->slot[slot_num].ts = ring->last_ts; #endif } @@ -173,9 +112,11 @@ struct adapter *adapter; adapter = (struct adapter *)device_get_softc(dev); + RINGMAP_LOCK(adapter->rm); if (ring != NULL) { RINGMAP_HW_SYNC_TAIL(adapter, ring); /* SW_TAIL ==> HW_TAIL */ } + RINGMAP_UNLOCK(adapter->rm); } @@ -185,9 +126,11 @@ struct adapter *adapter; adapter = (struct adapter *)device_get_softc(dev); + RINGMAP_LOCK(adapter->rm); if (ring != NULL) { RINGMAP_HW_SYNC_HEAD(adapter, ring); /* SW_TAIL ==> HW_HEAD */ } + RINGMAP_UNLOCK(adapter->rm); } @@ -199,9 +142,14 @@ rm_8254_interrupt(void *arg) { struct adapter *adapter = (struct adapter *) arg; + /* count interrupts */ - adapter->rm->ring->interrupts_counter++; + if ( (adapter->rm != NULL) && (adapter->rm->ring != NULL) && + adapter->rm->ring->td != NULL) { + + adapter->rm->ring->interrupts_counter++; + } } @@ -212,21 +160,14 @@ RINGMAP_INTR(start); - /* - * synchronize HEAD and TAIL with userrp and kernrp - * TODO: we want multithreading, it means we should later - * sync not one ring but many rings, each per thread - */ + rm_8254_sync_tail(adapter->dev, adapter->rm->ring); - if (adapter->rm != NULL) { - rm_8254_sync_tail(adapter->dev, adapter->rm->ring); - } - - #ifdef RINGMAP_TIMESTAMP + RINGMAP_LOCK(adapter->rm); if (adapter->rm->ring != NULL) { getmicrotime(&adapter->rm->ring->last_ts); } + RINGMAP_UNLOCK(adapter->rm); #endif RINGMAP_INTR(end); @@ -250,11 +191,6 @@ adapter = (struct adapter *)device_get_softc(dev); /* Check some pointers in the adapter structure */ - if (adapter == NULL){ - RINGMAP_ERROR(Adapter structure is not allocated!); - RINGMAP_ERROR(Probably driver is not loaded.); - return (-1); - } if (adapter->rx_buffer_area == NULL){ RINGMAP_ERROR(mbufs array is not allocated) return (-1); @@ -327,7 +263,7 @@ (bus_addr_t)vtophys(GET_DESCRIPTOR_P(adapter, slot_num)); #if (__RINGMAP_DEB) - rm_8254_print_slot(ring, slot_num); + ringmap_print_slot(ring, slot_num); #endif return (0); @@ -337,34 +273,8 @@ } -void -rm_8254_print_slot(struct ring *ring, unsigned int slot_number) -{ - printf("\n[%s] Slot Number: %d\n", __func__, slot_number); - printf("---------------- \n"); - - printf("physical addr of descriptor[%d] = 0x%X\n", slot_number, - (unsigned int) ring->slot[slot_number].descriptor.phys); - - printf("kernel addr of descriptor[%d] = 0x%X\n", slot_number, - (unsigned int) ring->slot[slot_number].descriptor.kern); - printf("physical addr of mbuf[%d] = 0x%X\n", slot_number, - (unsigned int) ring->slot[slot_number].mbuf.phys); - printf("kernel addr of mbuf[%d] = 0x%X\n", slot_number, - (unsigned int) ring->slot[slot_number].mbuf.kern); - - printf("physical addr of packet_buffer[%d] = 0x%X\n", slot_number, - (unsigned int) ring->slot[slot_number].packet.phys); - - printf("kernel addr of packet_buffer[%d] = 0x%X\n", slot_number, - (unsigned int) ring->slot[slot_number].packet.kern); - - printf("---------------- \n"); -} - - /* * Disable interrupts on adapter */ @@ -450,15 +360,20 @@ unsigned int rdt, rdh; struct ringmap *rm = NULL; - if ( (adapter == NULL) || - (adapter->rm == NULL) || - (adapter->rm->ring ) == NULL){ - RINGMAP_WARN(NULL pointer! Can not print rings pointers); + rm = adapter->rm; + + /* + * We should lock our data because while printing + * other process (for instance from other CPU) can + * free the memory regions that we are access in + * this functions + */ - return (0); - } + /* -> Critical Section: begin */ + RINGMAP_LOCK(rm); - rm = adapter->rm; + if ( (rm == NULL) || (rm->ring == NULL) ) + goto out; rdh = RINGMAP_HW_READ_HEAD(adapter); rdt = RINGMAP_HW_READ_TAIL(adapter); @@ -471,5 +386,10 @@ printf("== + userrp = %d \n", rm->ring->userrp); printf("== ++++++++++++++++++++++++++++++++++++++ \n\n"); +out: + + RINGMAP_UNLOCK(rm); + /* -> Critical Section: end */ + return (0); } ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_8254.h#16 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_e1000.h#8 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/net/ringmap.c#22 (text+ko) ==== @@ -38,6 +38,7 @@ int is_supported (unsigned int); int set_ringmap_funcs (struct ringmap *, unsigned int); void ringmap_close_cb (void *data); +void ringmap_print_slot(struct ring *, unsigned int); struct ringmap *(*get_ringmap_p)(device_t); device_t (*get_device_p)(struct cdev *); @@ -54,7 +55,6 @@ extern void rm_8254_sync_head(device_t, struct ring *); extern void rm_8254_delayed_interrupt_per_packet(struct ring *, int); extern struct ring *rm_8254_alloc_ring(device_t); -extern void rm_8254_free_ring(device_t, struct ring *); d_open_t ringmap_open; d_close_t ringmap_close; @@ -127,7 +127,6 @@ rm->funcs->sync_tail = rm_8254_sync_tail; rm->funcs->sync_head = rm_8254_sync_head; rm->funcs->alloc_ring = rm_8254_alloc_ring; - rm->funcs->free_ring = rm_8254_free_ring; get_ringmap_p = rm_8254_get_ringmap_p; get_device_p = rm_8254_get_device_p; @@ -160,15 +159,14 @@ RINGMAP_FUNC_DEBUG(begin); pci_dev_id = pci_get_device(dev); - controller_type = is_supported(pci_dev_id); /* Make sure we are support this controller */ + controller_type = is_supported(pci_dev_id); if (!(controller_type)) return (-1); rm = (struct ringmap *) contigmalloc (sizeof(struct ringmap), - M_DEVBUF, M_ZERO, 0, -1L, PAGE_SIZE, 0); - + M_DEVBUF, M_ZERO, 0, -1L, PAGE_SIZE, 0); if (rm == NULL) { RINGMAP_ERROR(Can not allocate space for ringmap structure); return (-1); @@ -208,6 +206,9 @@ /* Store adapters device structure */ rm->dev = dev; + /* Init the mutex to protecting our data */ + RINGMAP_LOCK_INIT(rm, device_get_nameunit(dev)); + /* set the pointer to ringmap in the adapters structure */ rm->funcs->set_ringmap_to_adapter(dev, rm); @@ -231,6 +232,8 @@ } destroy_dev(rm->cdev); + + RINGMAP_LOCK_DESTROY(rm); contigfree(rm->funcs, sizeof(struct ringmap_functions), M_DEVBUF); contigfree(rm, sizeof(struct ringmap), M_DEVBUF); @@ -252,6 +255,7 @@ int ringmap_open(struct cdev *cdev, int flag, int otyp, struct thread *td) { + int err = 0; struct ringmap *rm = NULL; RINGMAP_FUNC_DEBUG(start); @@ -268,33 +272,61 @@ return (EIO); } - + + /* + * I think it is safe to disable interupts while we allocate + * allocate memory for oure structures + */ + rm->funcs->disable_intr(rm->dev); + + /* -> Critical Section: begin */ + RINGMAP_LOCK(rm); if ( rm->dev == NULL ) { RINGMAP_ERROR(Null pointer to device structure of adapter); - return (EIO); + err = EIO; goto out; } /* Allocate ring */ - if ( rm->funcs->alloc_ring(rm->dev ) == NULL) { - RINGMAP_ERROR(Null pointer to ring the structure); + rm->ring = rm->funcs->alloc_ring(rm->dev); - return (EIO); - } - /* Check for any cases */ if ( rm->ring == NULL ) { RINGMAP_ERROR(Error! Please debug!); - return (EIO); + + err = EIO; goto out; } + + /* Set ring fields in the initial state */ + rm->ring->kern_wait_user = 0; + rm->ring->user_wait_kern = 0; + rm->ring->interrupts_counter = 0; + rm->ring->pkt_counter = 0; + rm->ring->size = SLOTS_NUMBER; /* Store pointer to the thread */ rm->ring->td = td; + /* + * Currently only one process only one time can open our device !!! + */ + if (!atomic_cmpset_int(&rm->open_cnt, 0, 1)){ + RINGMAP_ERROR(Sorry! Can not open device more then one time!); + atomic_readandclear_int(&rm->open_cnt); + + err = EIO; goto out; + } + +out: + RINGMAP_UNLOCK(rm); + /* -> Critical Section: end */ + + rm->funcs->enable_intr(rm->dev); + RINGMAP_FUNC_DEBUG(end); - return (0); + return (err); } @@ -313,12 +345,20 @@ return (0); } + rm->funcs->disable_intr(rm->dev); + atomic_readandclear_int(&rm->open_cnt); - if (rm->ring != NULL){ - rm->funcs->free_ring(rm->dev, rm->ring); - rm->ring = NULL; - } + /* -> Critical Section: begin */ + RINGMAP_LOCK(rm); + + if (rm->ring != NULL) + contigfree(rm->ring, sizeof(struct ring), M_DEVBUF); + + rm->ring = NULL; + + RINGMAP_UNLOCK(rm); + /* -> Critical Section: end */ RINGMAP_FUNC_DEBUG(end); @@ -330,6 +370,7 @@ ringmap_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr, int nprot, vm_memattr_t *memattr) { + int err = 0; struct ringmap *rm = NULL; RINGMAP_FUNC_DEBUG(start); @@ -342,22 +383,32 @@ RINGMAP_ERROR(Can not get pointer to ringmap structure); return (ENXIO); } + + /* -> Critical Section: begin */ + RINGMAP_LOCK(rm); + if (rm->ring == NULL){ RINGMAP_ERROR(Can not get pointer to ring structure); - return (ENXIO); + + err = ENXIO; goto out; } /* Check protections */ if (nprot & PROT_EXEC) { RINGMAP_WARN("PROT_EXEC ist set"); - return (ERESTART); + + err = ERESTART; goto out; } *paddr = vtophys(rm->ring); +out: + RINGMAP_UNLOCK(rm); + /* -> Critical Section: end */ + RINGMAP_FUNC_DEBUG(end); - return(0); + return(err); } @@ -396,9 +447,18 @@ /* Sleep and wait for new frames */ case IOCTL_SLEEP_WAIT: RINGMAP_IOCTL(Sleep and wait for new packets); + ringmap->ring->user_wait_kern++; ringmap->funcs->sync_head_tail(get_device_p(cdev), ringmap->ring); - err_sleep = tsleep(ringmap, (PRI_MIN) | PCATCH, "ioctl", 0); + + /* + * In the time: from user has called ioctl() until now could + * come the new packets. It means, before we are going to sleep + * it makes a sence to check if we really must do it :) + */ + if (RING_IS_EMPTY(ringmap->ring)) { + err_sleep = tsleep(ringmap, (PRI_MIN) | PCATCH, "ioctl", 0); + } break; case IOCTL_SYNC_HEAD_TAIL: @@ -419,3 +479,30 @@ return (err); } + +void +ringmap_print_slot(struct ring *ring, unsigned int slot_number) +{ + printf("\n[%s] Slot Number: %d\n", __func__, slot_number); + printf("---------------- \n"); + + printf("physical addr of descriptor[%d] = 0x%X\n", slot_number, + (unsigned int) ring->slot[slot_number].descriptor.phys); + + printf("kernel addr of descriptor[%d] = 0x%X\n", slot_number, + (unsigned int) ring->slot[slot_number].descriptor.kern); + + printf("physical addr of mbuf[%d] = 0x%X\n", slot_number, + (unsigned int) ring->slot[slot_number].mbuf.phys); + + printf("kernel addr of mbuf[%d] = 0x%X\n", slot_number, + (unsigned int) ring->slot[slot_number].mbuf.kern); + + printf("physical addr of packet_buffer[%d] = 0x%X\n", slot_number, + (unsigned int) ring->slot[slot_number].packet.phys); + + printf("kernel addr of packet_buffer[%d] = 0x%X\n", slot_number, + (unsigned int) ring->slot[slot_number].packet.kern); + + printf("---------------- \n"); +} ==== //depot/projects/soc2010/ringmap/current/sys/net/ringmap.h#22 (text+ko) ==== @@ -1,11 +1,3 @@ -/* Minimum distance to be kept between the userrp and RDT to provide a - * guarantee to userspace processes that the previous n buffer positions - * behind userrp will not be overwritten - * - * Currently not used!!! - * */ -#define RING_SAFETY_MARGIN 3 - /* * value for number of descriptors (a.k.a. slots in the ringbuffer) */ @@ -20,12 +12,6 @@ #define MOD_NAME "if_ringmap.ko" /* - * Messaure statistics for each pkt. - * at the moment not used, but will be - */ -#define EACH_PKT 20 - -/* * Driver works only with device wich has the following device ID. If 0 * then work with all devices that was found and accepted in the "probe" * function. @@ -137,13 +123,22 @@ /* Counts number of hardware interrupts */ unsigned long long interrupts_counter; + /* + * Slot which currently processed by driver in context of + * delayed interupt + */ unsigned int volatile cur_slot_kern; + + /* + * Slot which currently processed by user-space process + * in the pcap_read_ringmap() function (ringmap_pcap.c) + */ unsigned int volatile cur_slot_user; /* * Number of received packets. This variable should be changed only in * user-space. We want to count the packets, that was seen by user-space - * process + * process. I am not sure we are need it :( */ unsigned long long pkt_counter; @@ -181,6 +176,9 @@ /* Hardware dependent functions */ struct ringmap_functions *funcs; + /* Mutex that should protect the data allocated in the ring */ + struct mtx ringmap_mtx; + /* Our ring that have to be mapped in space of user process */ struct ring *ring; }; @@ -229,9 +227,9 @@ void (*delayed_isr_per_packet)(struct ring *, int); /* - * This function synchronize the tail and head hardware registers - * with head and tail software varibles, that are visible from - * software process. + * Next functions synchronize the tail and head hardware registers + * with head and tail software varibles which are also visible from + * user-space process. * * Synchronisation rules: * 1. SYNC_HEAD: HARDWARE_HEAD => SOFTWARE_HEAD @@ -255,10 +253,16 @@ /* Alloc memory for our ring and initialize the slots */ struct ring *(*alloc_ring)(device_t); +}; - /* Free memory that was allocated for the ring */ - void (*free_ring)(device_t, struct ring *); -}; +/* MUTEX */ +#define RINGMAP_LOCK_INIT(rm, _name) \ + mtx_init(&(rm)->ringmap_mtx, _name, "RINGMAP Lock", MTX_DEF) +#define RINGMAP_LOCK_DESTROY(rm) mtx_destroy(&(rm)->ringmap_mtx) +#define RINGMAP_LOCK(rm) mtx_lock(&(rm)->ringmap_mtx) +#define RINGMAP_TRYLOCK(rm) mtx_trylock(&(rm)->ringmap_mtx) +#define RINGMAP_UNLOCK(rm) mtx_unlock(&(rm)->ringmap_mtx) + #endif /* _KERNEL */ @@ -420,7 +424,7 @@ (unsigned int)adapter->rx_buffer_area[i].m_head->m_data,\ (unsigned int)adapter->rx_desc_base[i].buffer_addr); -#define PRINT_SOME_BYTES_FROM_PKT(adapter, i) \ +#define PRINT_SOME_BYTES_FROM_PKT(adapter, i) \ printf("=+= [%s] SOME BYTES FROM PKT: %hhX %hhX %hhX %hhX %hhX\n", \ __func__, \ adapter->rx_buffer_area[i].m_head->m_data[0], \ @@ -444,7 +448,7 @@ printf("\n=+= =============================\n"); \ printf("=+= Slot Number: %d \n", (i)); \ printf("=+= Intrr num: %llu\n", (ring)->slot[(i)].intr_num); \ - printf("=+= Time stamp: %llu\n", (unsigned long long)(((ring)->slot[(i)].ts.tv_sec*1000000 + (ring)->slot[(i)].ts.tv_usec))); \ + printf("=+= Time stamp: %llu\n", (unsigned long long)(((ring)->slot[(i)].ts.tv_sec*1000000 + (ring)->slot[(i)].ts.tv_usec))); \ printf("=+= Accepted: %d\n", (ring)->slot[(i)].is_ok); \ PRINT_SOME_BYTES_FROM_PKT((arg), (i)); \ printf("=+= =============================\n\n"); \ ==== //depot/projects/soc2010/ringmap/scripts/build_ringmap.sh#6 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/scripts/set_ringmap.sh#7 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/scripts/tailf_ringmap_msgs.sh#2 (text+ko) ====