From owner-p4-projects@FreeBSD.ORG Wed Jun 23 16:18:44 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 152851065674; Wed, 23 Jun 2010 16:18: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 CAB041065670 for ; Wed, 23 Jun 2010 16:18:43 +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 B758B8FC17 for ; Wed, 23 Jun 2010 16:18:43 +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 o5NGIh10031623 for ; Wed, 23 Jun 2010 16:18:43 GMT (envelope-from afiveg@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o5NGIh7T031621 for perforce@freebsd.org; Wed, 23 Jun 2010 16:18:43 GMT (envelope-from afiveg@FreeBSD.org) Date: Wed, 23 Jun 2010 16:18:43 GMT Message-Id: <201006231618.o5NGIh7T031621@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 180153 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: Wed, 23 Jun 2010 16:18:44 -0000 http://p4web.freebsd.org/@@180153?ac=10 Change 180153 by afiveg@cottonmouth on 2010/06/23 16:17:44 Improving comments and adding new macros Affected files ... .. //depot/projects/soc2010/ringmap/current/contrib/libpcap/ringmap_pcap.c#2 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_lem.c#10 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_lem.h#8 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_8254.c#9 edit .. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_8254.h#7 edit .. //depot/projects/soc2010/ringmap/current/sys/net/ringmap.c#13 edit .. //depot/projects/soc2010/ringmap/current/sys/net/ringmap.h#13 edit Differences ... ==== //depot/projects/soc2010/ringmap/current/contrib/libpcap/ringmap_pcap.c#2 (text+ko) ==== @@ -334,15 +334,19 @@ again1: - printf("user kern distance = %d\n", USER_TO_KERN_RING_DISTANCE(p->ring)); +#ifdef __RINGMAP_DEB + printf("[%s] user kern distance = %d\n", __func__, + SW_TAIL_TO_HEAD_DIST(p->ring)); +#endif if ( RING_IS_EMPTY(p->ring) ) { + /* Sleep and wait for new incoming packets */ ioctl(ringmap_cdev_fd, IOCTL_SLEEP_WAIT); goto again1; } if (cnt == -1) - cnt = USER_TO_KERN_RING_DISTANCE(p->ring); + cnt = SW_TAIL_TO_HEAD_DIST(p->ring); for (ws = cnt ; ( (ws) && (RING_NOT_EMPTY(p->ring)) ) ; ) { @@ -362,11 +366,12 @@ (*callback)(user, &pkthdr, datap); - INC_USER_POINTER(p->ring); + INC_TAIL(p->ring); --ws; + } - } + RINGMAP_FUNC_DEBUG(end); return (cnt - ws); } ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_lem.c#10 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_lem.h#8 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_8254.c#9 (text+ko) ==== @@ -35,15 +35,25 @@ extern void lem_disable_intr(struct adapter *); +/* + * This function synchronize the tail and head hardware registers + * with head and tail software varibles, that are visible from + * software process. + * + * Synchronisation rules: + * 1. SYNC_HEAD: ring->kernrp = RDH + * 2. SYNC_TAIL: RDT = ring->userrp + */ void rm_8254_sync_head_tail(device_t dev, struct ring *ring) { struct adapter *adapter; adapter = (struct adapter *)device_get_softc(dev); - ring->kernrp = RINGMAP_HW_READ_HEAD(adapter); - RINGMAP_HW_SYNC_TAIL(adapter, ring); - adapter->rm->ring->hw_RDT = ring->userrp; + RINGMAP_HW_SYNC_HEAD(adapter, ring); /* SW_HEAD <== HW_HEAD */ + RINGMAP_HW_SYNC_TAIL(adapter, ring); /* SW_TAIL ==> HW_TAIL */ + + adapter->rm->ring->hw_RDT = RINGMAP_HW_READ_TAIL(adapter); } @@ -126,7 +136,10 @@ ring->kern_wait_user = 0; ring->user_wait_kern = 0; ring->interrupts_counter = 0; - RINGMAP_HW_WRITE_TAIL(adapter, SLOTS_NUMBER - 1); + + RINGMAP_HW_WRITE_TAIL(adapter, + (R_MODULO(RINGMAP_HW_READ_HEAD(adapter) - 1))); + ring->userrp = RINGMAP_HW_READ_TAIL(adapter); ring->size = SLOTS_NUMBER; ==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_8254.h#7 (text+ko) ==== @@ -25,6 +25,9 @@ #define RINGMAP_HW_READ_HEAD(adapter) \ RINGMAP_HW_READ_REG(&adapter->hw, E1000_RDH(0)) +#define RINGMAP_HW_SYNC_HEAD(adapter, ring) \ + SW_HEAD(ring) = RINGMAP_HW_READ_HEAD(adapter); + #define RINGMAP_HW_SYNC_TAIL(adapter, ring) \ RINGMAP_HW_WRITE_REG(&adapter->hw, E1000_RDT(0), ring->userrp) ==== //depot/projects/soc2010/ringmap/current/sys/net/ringmap.c#13 (text+ko) ==== ==== //depot/projects/soc2010/ringmap/current/sys/net/ringmap.h#13 (text+ko) ==== @@ -1,22 +1,32 @@ /* 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 */ + * behind userrp will not be overwritten + * + * Currently not used!!! + * */ #define RING_SAFETY_MARGIN 3 -/* Max value for number of descriptors (a.k.a. slots in the ringbuffer) is 4096 */ +/* + * value for number of descriptors (a.k.a. slots in the ringbuffer) + */ #define SLOTS_NUMBER 16 -/* Prefix for name of device (for example /dev/ringmap_cdev_0 will full name) */ +/* + * Prefix for name of device (for example /dev/ringmap_cdev0 will full name) + */ #define RINGMAP_DEVICE "ringmap_cdev" /* Name of module to be loaded*/ #define MOD_NAME "if_ringmap.ko" -/* Messaure statistics for each pkt */ +/* + * Messaure statistics for each pkt. + * at the moment not used, but will be + */ #define EACH_PKT 20 /* - * Driver have to work only with device wich has the following device ID if 0 + * 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. * @@ -24,7 +34,7 @@ */ #define DEV_ID 0 -/* Enable/Disable Transiv */ +/* Enable/Disable Transiv. If 0, then the adapter will only receive pkts */ #define RINGMAP_TX_ENABLE 0 @@ -122,7 +132,7 @@ }; struct ringmap { - /* Device structure of network adapters */ + /* Device structure of network adapter */ device_t dev; /* Char device for communications between user and kernel spaces */ @@ -142,12 +152,61 @@ }; struct ringmap_functions { + +/* + * Set pointer to the ringmap structure into the adapters + * driver structure. + */ int (*set_ringmap_to_adapter)(device_t, struct ringmap*); + +/* + * In some situations it is safe to disable + * interrupts on adapter. + */ void (*enable_intr)(device_t); void (*disable_intr)(device_t); + +/* + * Initialize the ring slots with pointers to the + * mbufs, packets buffers and descriptors. + */ int (*init_slots)(struct ring *, device_t); + +/* + * This function should be calld from ISR. It should contain + * the very fast executable operations (don't sleep!). + */ void (*interrupt)(void *); + +/* + * This function should be calld from delayed interrupt + * function. It can contain operations that must not be + * very fast. + */ void (*delayed_interrupt)(void *); + + + +/* + * This function synchronize the tail and head hardware registers + * with head and tail software varibles, that are visible from + * software process. + * + * Synchronisation rules: + * 1. SYNC_HEAD: HARDWARE_HEAD => SOFTWARE_HEAD + * set value from hardware HEAD register into the software visible + * HEAD-variable: ring->kernrp. The User-space process shouldn't touch + * the ring->kernrp variable. Only hardware increment the value in the + * HEAD register onto adapters chip while receiving new packets, and only + * driver (kernel) synchronize then hardware HEAD with ring->kernrp. + * + * 2. SYNC_TAIL: SOFTWARE_TAIL => HARDWARE_TAIL + * set value from software TAIL-variable: ring->userrp into the hardware + * TAIL-register. Hardware shouldn't change the content of TAIL-register. + * Software after reading one packet in RAM increment the value of + * ring->userrp. Kernel will check this value and set it into the + * hardware TAIL-register. + */ void (*sync_head_tail)(device_t, struct ring *); }; @@ -181,72 +240,57 @@ * Arithmetic in Ring Buffer **********************************************/ -#define R_MODULO(a,b) \ +/* Software HEAD and TAIL ring pointers */ +#define SW_TAIL(ringp) ((ringp)->userrp) +#define SW_HEAD(ringp) ((ringp)->kernrp) + +/* + * The hardware HEAD and TAIL are defined in the hardware dependent + * header files + */ + +#define RING_MODULO(a,b) \ ( ((unsigned int)(a)) % ((unsigned int)(b)) ) /* Distance from "a" to "b" in ring: r = (b-a) mod (size) */ -#define RING_DISTANCE(r,a,b,size) \ - (r) = R_MODULO(((b) - (a)), (size)); +#define RING_DISTANCE(a,b,size) \ + (RING_MODULO((b)-(a), (size))) -#define R_DISTANCE(a,b,size) \ - (R_MODULO((b)-(a), (size))) +#define R_MODULO(a) \ + RING_MODULO((a), (SLOTS_NUMBER)) -/* Distance from KERN pointer to USER pointer */ -#define KERN_TO_USER_DIST(r, ringp) \ - do { \ - RING_DISTANCE((r), (ringp)->kernrp, (ringp)->userrp, SLOTS_NUMBER); \ - if ((r) == 0) (r) = SLOTS_NUMBER; \ - } while (0); +#define R_DISTANCE(a, b) \ + RING_DISTANCE((a), (b), (SLOTS_NUMBER)) -/* Distance from USER pointer to KERN pointer */ -#define USER_TO_KERN_DIST(r, ringp) \ - do { \ - RING_DISTANCE((r), (ringp)->userrp, (ringp)->kernrp, SLOTS_NUMBER); \ - } while(0); +/* Distance from head to tail in ring */ +#define SW_HEAD_TO_TAIL_DIST(ringp) \ + R_DISTANCE(SW_HEAD(ringp), SW_TAIL(ringp)) -/* Distance from KERN to USER pointer */ -#define KERN_TO_USER_RING_DISTANCE(ringp) \ - (((ringp)->userrp == (ringp)->kernrp) ? 0 : R_DISTANCE((ringp)->kernrp, (ringp)->userrp, SLOTS_NUMBER)) +/* Distance from tail to head in ring */ +#define SW_TAIL_TO_HEAD_DIST(ringp) \ + ((SW_TAIL(ringp) == SW_HEAD(ringp)) ? SLOTS_NUMBER : \ + R_DISTANCE(SW_TAIL(ringp), SW_HEAD(ringp))) -/* Distance from USER to KERN pointer */ -#define USER_TO_KERN_RING_DISTANCE(ringp) \ - (((ringp)->userrp == (ringp)->kernrp) ? SLOTS_NUMBER : R_DISTANCE((ringp)->userrp, (ringp)->kernrp, SLOTS_NUMBER)) +#define INC_TAIL(ringp) \ + (SW_TAIL(ringp)) = R_MODULO(SW_TAIL(ringp) + 1); -#define RING_IS_EMPTY(ringp) \ - ((USER_TO_KERN_RING_DISTANCE(ringp)) == 1) +#define RING_IS_EMPTY(ringp) \ + ((SW_TAIL_TO_HEAD_DIST(ringp)) == 1) -#define RING_NOT_EMPTY(ringp) \ - ((USER_TO_KERN_RING_DISTANCE(ringp)) > 1) +#define RING_NOT_EMPTY(ringp) \ + ((SW_TAIL_TO_HEAD_DIST(ringp)) != 1) -#define RING_IS_FULL(ringp) \ - ((KERN_TO_USER_RING_DISTANCE(ringp)) == 0) +#define RING_IS_FULL(ringp) \ + ((SW_HEAD_TO_TAIL_DIST(ringp)) == 0) -/* Increment of USER pointer. (KERN pointer is incremented by Hardware) */ -#define INC_USER_POINTER(ringp) \ - ((ringp)->userrp) = R_MODULO(((ringp)->userrp + 1), SLOTS_NUMBER); +#define RING_SLOT(ringp, i) \ + ((ringp)->slot[(i)]) -/* Add "a" to USER pointer */ -#define ADD_USER_POINTER(ringp, a) \ - ((ringp)->userrp) = R_MODULO(((ringp)->userrp + a), SLOTS_NUMBER); +#define TAIL_SLOT(ringp) \ + RING_SLOT((ringp), (SW_TAIL((ringp)))) -/* Next Operationts are only in Kern usefull because they set hardware registers */ -#ifdef _KERNEL - -/* Read value from RDH, set RDT = RDH - RING_SAFETY_MARGIN */ -/* -#define RINGMAP_INIT(ringp, adapter) \ - do{ \ - (ringp)->kern_wait_user = 0; \ - (ringp)->user_wait_kern = 0; \ - (ringp)->interrupts_counter = 0; \ - (ringp)->size = SLOTS_NUMBER; \ - (ringp)->kernrp = RINGMAP_HW_READ_REG(&(adapter)->hw, E1000_RDH(0)); \ - (ringp)->userrp = (ringp)->kernrp; \ - RINGMAP_HW_WRITE_REG(&(adapter)->hw, E1000_RDT(0), R_MODULO(((ringp)->userrp) - RING_SAFETY_MARGIN, SLOTS_NUMBER)); \ - }while(0); -*/ -#endif - +#define TAIL_PACKET(ringp) \ + TAIL_SLOT(ringp).packet /* * DEBUG OUTPUT