PERFORCE change 180153 for review
Alexandre Fiveg
afiveg at FreeBSD.org
Wed Jun 23 16:18:44 UTC 2010
http://p4web.freebsd.org/@@180153?ac=10
Change 180153 by afiveg at 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
More information about the p4-projects
mailing list