Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 17 Oct 2010 20:43:31 GMT
From:      Alexandre Fiveg <afiveg@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 184838 for review
Message-ID:  <201010172043.o9HKhV62043651@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@184838?ac=10

Change 184838 by afiveg@cottonmouth on 2010/10/17 20:42:25

	Significantly reduced hardware-dependent part of code. Most of the function are removed into hardware-independent ringmap.c. The hardware-dependent function are now responsible only for accessing registers (HEAD, TAIL) and receive buffers allocated as array in the generic driver. capt_object structure is extended: the new members: rx/tx_buffers for accessing memory regions allocated by generic driver for receive and transmit, hw_rx/tx_ring for accessing hardware registers like HEAD and TAIL. Currently supported controllers: Intel 8254x (driver if_lem). Unfortunately, because of broken 10GbE adapter I've received for GSoC the work on 10GbE is stopped.  

Affected files ...

.. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_lem.c#35 edit
.. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_8254.c#35 edit
.. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_8254.h#32 delete
.. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_e1000.h#24 delete
.. //depot/projects/soc2010/ringmap/current/sys/net/ringmap.c#49 edit
.. //depot/projects/soc2010/ringmap/current/sys/net/ringmap.h#49 edit
.. //depot/projects/soc2010/ringmap/current/sys/net/ringmap_kernel.h#19 edit
.. //depot/projects/soc2010/ringmap/doc/slides/Makefile#1 add
.. //depot/projects/soc2010/ringmap/doc/slides/ringmap_slides.tex#1 add
.. //depot/projects/soc2010/ringmap/doc/slides/section/Background/Capturing.tex#1 add
.. //depot/projects/soc2010/ringmap/doc/slides/section/Motivation/Goal.tex#1 add
.. //depot/projects/soc2010/ringmap/doc/slides/section/Motivation/Problem.tex#1 add
.. //depot/projects/soc2010/ringmap/doc/slides/section/Performance/Results.tex#1 add
.. //depot/projects/soc2010/ringmap/doc/slides/section/Performance/Setup.tex#1 add
.. //depot/projects/soc2010/ringmap/doc/slides/section/Solution/Generic2Ringmap.tex#1 add
.. //depot/projects/soc2010/ringmap/doc/slides/section/Solution/Overview.tex#1 add
.. //depot/projects/soc2010/ringmap/doc/slides/section/Solution/Ringmap.tex#1 add
.. //depot/projects/soc2010/ringmap/doc/slides/section/Summary/AchievedGoals.tex#1 add
.. //depot/projects/soc2010/ringmap/doc/slides/section/Summary/FutureWorks.tex#1 add
.. //depot/projects/soc2010/ringmap/scripts/build_ringmap.sh#31 edit
.. //depot/projects/soc2010/ringmap/scripts/set_ringmap.sh#32 edit
.. //depot/projects/soc2010/ringmap/scripts/tailf_ringmap_msgs.sh#26 edit

Differences ...

==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_lem.c#35 (text+ko) ====

@@ -270,7 +270,7 @@
 extern struct ringmap * ringmap_attach(device_t, struct ringmap_functions *);
 extern int ringmap_detach (device_t);
 
-extern struct ringmap_functions ringmap_8254_f;
+extern struct ringmap_functions ringmap_8254_functions;
 #endif 
 
 #ifdef DEVICE_POLLING
@@ -670,7 +670,7 @@
 	    device_get_nameunit(dev));
 
 #ifdef RINGMAP
-	adapter->rm = ringmap_attach (dev, &ringmap_8254_f);
+	adapter->rm = ringmap_attach (dev, &ringmap_8254_functions);
 	if (adapter->rm == NULL) {
 		goto err_rx_struct;
 	}
@@ -3498,7 +3498,7 @@
 	}
 
 #ifdef RINGMAP
-		adapter->rm->funcs->delayed_isr(adapter);
+		co = adapter->rm->funcs->delayed_isr(adapter, adapter->rm);
 #endif
 
 	while ((current_desc->status & E1000_RXD_STAT_DD) &&
@@ -3556,8 +3556,8 @@
 
 #ifdef RINGMAP
 			RINGMAP_LOCK(adapter->rm);
-			if (adapter->rm->open_cnt)
-				adapter->rm->funcs->delayed_isr_per_packet(adapter->dev, i);
+			if ((adapter->rm->open_cnt) && (co != NULL))
+				adapter->rm->funcs->per_packet_iteration(co, i);
 			RINGMAP_UNLOCK(adapter->rm);
 #endif
 
@@ -3670,12 +3670,8 @@
 
 #ifdef RINGMAP
 	RINGMAP_LOCK(adapter->rm);
-	SLIST_FOREACH(co, &adapter->rm->object_list, objects) {
-		adapter->rm->funcs->sync_head(co);
-		if (RING_NOT_EMPTY(co->ring)){
+		if ((co != NULL) && (RING_NOT_EMPTY(co->ring)))
 			wakeup(co->ring);
-		}
-	}
 	RINGMAP_UNLOCK(adapter->rm);
 #endif 
 
@@ -3685,7 +3681,7 @@
 	if (--i < 0)
 		i = adapter->num_rx_desc - 1;
 
-	/* RINGMAP: Don't write RDT. We do it in sync_tail() */
+	/* RINGMAP: Don't write RDT. We'll do it after user has read packet */
 #ifndef RINGMAP
 	E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
 #endif 

==== //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_8254.c#35 (text+ko) ====

@@ -17,249 +17,92 @@
 
 #include "e1000_api.h"
 #include "if_lem.h"
-#include "ringmap_8254.h"
 
-int rm_8254_set_slot(struct capt_object *, unsigned int);
-void rm_8254_interrupt(void *);
-void rm_8254_delayed_interrupt(void *);
-void rm_8254_delayed_interrupt_per_packet(void *, int);
-int rm_8254_print_ring_pointers(struct adapter *);
-void rm_8254_sync_tail(struct capt_object *);
-void rm_8254_sync_head(struct capt_object *);
-struct capt_object * rm_8254_find_next(struct adapter *);
 int rm_8254_set_queue(struct capt_object *, unsigned int);
+unsigned int rm_8245_get_rdh(void *hw_ring);
+unsigned int rm_8245_get_rdt(void *hw_ring);
+void rm_8245_set_rdt(unsigned int val, void *hw_ring);
+struct mbuf * rm_8254_get_mbuf(void *buffer_area, unsigned int num);
+vm_offset_t rm_8254_get_packet(void *buffer_area, unsigned int num);
+vm_offset_t rm8254_get_rx_desc(void * rx_desc_area, unsigned int num);
+
 
 extern devclass_t em_devclass;
-extern void ringmap_print_slot(struct ring *, unsigned int);
-extern void print_capt_obj(struct capt_object *);
-extern int ringmap_filter(struct capt_object *, int);
 
 
-struct ringmap_functions ringmap_8254_f = {
-	rm_8254_interrupt,
-	rm_8254_delayed_interrupt,
-	rm_8254_delayed_interrupt_per_packet,
-	rm_8254_sync_tail,
-	rm_8254_sync_head,
-	rm_8254_set_slot,
-	rm_8254_set_queue,
+struct ringmap_functions ringmap_8254_functions = {
+	.isr = NULL,
+	.delayed_isr = NULL,
+	.per_packet_iteration = NULL,
+	.get_head = rm_8245_get_rdh,
+	.get_tail = rm_8245_get_rdt,
+	.set_tail = rm_8245_set_rdt,
+	.get_mbuf = rm_8254_get_mbuf,
+	.get_packet = rm_8254_get_packet,
+	.set_queue = rm_8254_set_queue,
+	.pkt_filter = NULL,
 };
 
 
-/* 
- * Write the userrp into the RDT register
- * 2. SYNC_TAIL: RDT =  ring->userrp
- */
-void 
-rm_8254_sync_tail(struct capt_object *co)
+struct mbuf * 
+rm_8254_get_mbuf(void *buffer_area, unsigned int num)
 {
-	struct adapter *adapter = (struct adapter *)device_get_softc(co->rm->dev);
+	struct em_buffer *buf = (struct em_buffer *)buffer_area;
+	return (buf[num].m_head);
+}
 
-	RINGMAP_HW_SYNC_TAIL(adapter, co->ring);
-}
 
-/* Set value from RDH to the ring->kernrp*/
-void 
-rm_8254_sync_head(struct capt_object *co)
+vm_offset_t
+rm_8254_get_packet(void *buffer_area, unsigned int num)
 {
-	struct adapter *adapter = (struct adapter *)device_get_softc(co->rm->dev);
-
-	RINGMAP_HW_SYNC_HEAD(adapter, co->ring); 
+	struct mbuf *mb = rm_8254_get_mbuf(buffer_area, num);
+	return ((vm_offset_t)mb->m_data);
 }
 
 
-/* 
- * This should be called from ISR. Other interrupts are disallowed!
- * It means the functions must be as small as possible
- */
-void inline 
-rm_8254_interrupt(void *arg)
+unsigned int
+rm_8245_get_rdh(void *hw_ring)
 {
-	/* Do nothing ... */
-   return;	
+	return (E1000_READ_REG((struct e1000_hw *)hw_ring, E1000_RDH(0)));
 }
 
 
-void 
-rm_8254_delayed_interrupt(void *context)
+unsigned int
+rm_8245_get_rdt(void *hw_ring)
 {
-	struct adapter	*adapter = (struct adapter *)context;
-	struct capt_object *co = NULL;
-	struct timeval	last_ts;
-
-	RINGMAP_INTR(start);
-
-	RINGMAP_LOCK(adapter->rm);
-	/* Do the next steps only if there is capturing process */ 
-	if (adapter->rm->open_cnt > 0) {
-		getmicrotime(&last_ts);
-		rm_8254_sync_tail(rm_8254_find_next(adapter));
-
-		SLIST_FOREACH(co, &adapter->rm->object_list, objects) {
-			if (co->ring != NULL) {
-#if (RINGMAP_INTR_DEB)
-				PRINT_RING_PTRS(co->ring);
-#endif
-				co->ring->last_ts = last_ts;
-				++co->ring->intr_num;
-			}
-		}
-	}
-	RINGMAP_UNLOCK(adapter->rm);
-
-	RINGMAP_INTR(end);
+	return (E1000_READ_REG((struct e1000_hw *)hw_ring, E1000_RDT(0)));
 }
 
 
-void 
-rm_8254_delayed_interrupt_per_packet(void *context, int slot_num)
+void
+rm_8245_set_rdt(unsigned int val, void *hw_ring)
 {
-	device_t dev = (device_t)context;
-	struct capt_object *co = NULL;
-	struct adapter *adapter = NULL;
-	struct ringmap *rm = NULL;
-
-	adapter = (struct adapter *)device_get_softc(dev);
-	rm = adapter->rm;
-
-	RINGMAP_INTR(start);
-
-	SLIST_FOREACH(co, &rm->object_list, objects) {
-		if (co->ring != NULL) {
-			co->ring->slot[slot_num].is_ok = 1;
-			co->ring->slot[slot_num].intr_num = co->ring->intr_num;
-			
-			ringmap_filter(co, slot_num);
-
-#ifdef RINGMAP_TIMESTAMP
-			co->ring->slot[slot_num].ts = co->ring->last_ts;
-#endif 
-#if (RINGMAP_INTR_DEB)
-			PRINT_SLOT((co->ring), (slot_num));
-#endif 
-		}
-	}
-
-	RINGMAP_INTR(end);
+	E1000_WRITE_REG((struct e1000_hw *)hw_ring, E1000_RDT(0), val);
 }
 
 
-/* Returns the ring which TAIL pointer is mostly near to to the HEAD(RDH) */
-struct capt_object *
-rm_8254_find_next(struct adapter *adapter)
+int 
+rm_8254_set_queue(struct capt_object *co, unsigned int i)
 {
-	unsigned int rdh, rdt, dist, min_dist = SLOTS_NUMBER;
-	struct ringmap *rm = adapter->rm;
-	struct capt_object *co = NULL, *min_co = NULL;
-
-	rdh = RINGMAP_HW_READ_HEAD(adapter);
-
-	SLIST_FOREACH(co, &rm->object_list, objects) {
-		rdt = co->ring->userrp;
-		dist = R_DISTANCE(rdh, rdt);
-		if (dist <= min_dist) {
-			min_dist = dist;
-			min_co = co;
-		}
-	}
-
-	return (min_co);
-}
-
 
-
-int
-rm_8254_set_slot(struct capt_object *co, unsigned int slot_num)
-{
 	device_t dev = NULL; 	
 	struct adapter *adapter = NULL; 
-	struct ring *ring = NULL; 
-
-#if (__RINGMAP_DEB)
-	printf("[%s] Set slot: %d\n", __func__, slot_num);
-#endif
 
 	dev = co->rm->dev;
 	adapter = (struct adapter *)device_get_softc(dev);
-	ring = co->ring;
-
-	/* First check ALL pointers */
-	if (co == NULL) {
-		RINGMAP_ERROR(Pointer to capturing object is NULL);
-		goto fail;
-	}
-	if (co->rm == NULL) {
-		RINGMAP_ERROR(Pointer to ringmap is NULL);
-		goto fail;
-	}
-	if (GET_MBUF_P(adapter, slot_num) == NULL){
-		RINGMAP_ERROR(Pointer to mbuf is NULL);
-		goto fail;
-	}
-	if (GET_PACKET_P(adapter, slot_num) == NULL){
-		RINGMAP_ERROR(Pointer to packet is NULL);
-		goto fail;
-	}
-	if (GET_DESCRIPTOR_P(adapter, slot_num) == NULL){
-		RINGMAP_ERROR(Pointer to descriptor is NULL);
-		goto fail;
-	}
 
-	/* Now if everything is Ok, we can initialize ring pointers */
-	ring->slot[slot_num].mbuf.kern = 
-		(vm_offset_t)GET_MBUF_P(adapter, slot_num);
-	ring->slot[slot_num].mbuf.phys = 
-		(bus_addr_t)vtophys(GET_MBUF_P(adapter, slot_num));
 
-	ring->slot[slot_num].packet.kern = 
-		(vm_offset_t)GET_PACKET_P(adapter, slot_num);
-	ring->slot[slot_num].packet.phys = 
-		(bus_addr_t)vtophys(GET_PACKET_P(adapter, slot_num));
+	co->hw_rx_ring = &adapter->hw;
+	co->hw_tx_ring = &adapter->hw;
 
-	ring->slot[slot_num].descriptor.kern = 
-		(vm_offset_t)GET_DESCRIPTOR_P(adapter, slot_num);
-	ring->slot[slot_num].descriptor.phys = 
-		(bus_addr_t)vtophys(GET_DESCRIPTOR_P(adapter, slot_num));
+	co->rx_buffers = adapter->rx_buffer_area;
+	co->tx_buffers = adapter->tx_buffer_area;
 
-	return (0);
+	co->rx_desc_base = adapter->rx_desc_base;
+	co->tx_desc_base = adapter->tx_desc_base;
 
-fail:
-	RINGMAP_ERROR(Probably you have to do: ifconfig up);
-	return (-1);
-}
-
-
-/* Print the values from RDT and RDH */
-int 
-rm_8254_print_ring_pointers(struct adapter *adapter)
-{
-	unsigned int rdt, rdh;
-	struct ringmap *rm = NULL;
-
-	rm = adapter->rm;
-	
-	if (rm == NULL)
-		goto out;
-
-	rdh = RINGMAP_HW_READ_HEAD(adapter);
-	rdt = RINGMAP_HW_READ_TAIL(adapter);
-
-	printf("\n==  +++++++++  RING POINTERS  ++++++++++++ \n");
-	printf("==  +  HW HEAD = %d (KERN POINTER)\n", rdh);
-	printf("==  +  HW TAIL = %d (USER POINTER)\n", rdt);
-	printf("==  ++++++++++++++++++++++++++++++++++++++ \n\n");
-
-out:
-	return (0);
-}
-
-
-/* 8254x controllers have not multiqueue support: que = NULL */
-int 
-rm_8254_set_queue(struct capt_object *co, unsigned int i)
-{
-	/* No multiqueue for 8254 */
-	co->que = NULL;
+	/* Interrupt context is adapter structure. Look in if_lem.h */
+	co->intr_context = device_get_softc(co->rm->dev);
 
 	return (0);
 }

==== //depot/projects/soc2010/ringmap/current/sys/net/ringmap.c#49 (text+ko) ====

@@ -45,7 +45,10 @@
 void print_capt_obj(struct capt_object *);
 struct ringmap * cdev2ringmap(struct cdev *);
 struct ringmap * dev2ringmap(device_t);
-int ringmap_filter(struct capt_object *, int);
+void ringmap_bpf_filter(struct capt_object *, int);
+void per_packet_iteration(struct capt_object *, int );
+struct capt_object * ringmap_delayed_isr(void *context, struct ringmap *rm);
+int set_slot(struct capt_object *co, unsigned int slot_num);
 
 d_open_t	ringmap_open;
 d_close_t	ringmap_close;
@@ -66,9 +69,11 @@
 static struct ringmap_global_list ringmap_list_head = 
 		SLIST_HEAD_INITIALIZER(ringmap_list_head);
 
+
 /*
- * Will called from if_em.c before returning from 
- * em_attach() function.  
+ * The function should be called from attach function of generic network driver.
+ * Here the ringmap structure is allocated and the character special device for 
+ * the communication with user is created.
  */
 struct ringmap *
 ringmap_attach(device_t dev, struct ringmap_functions *rf) 
@@ -77,9 +82,9 @@
 
 	RINGMAP_FUNC_DEBUG(begin);
 
+	/* Allocate ringmap */
 	MALLOC(rm, struct ringmap *, sizeof(struct ringmap), 
 			M_DEVBUF, (M_ZERO | M_WAITOK));
-
 	if (rm == NULL) { 
 		RINGMAP_ERROR(Can not allocate space for ringmap structure);
 		return (NULL);
@@ -87,10 +92,10 @@
 
 	/* 
 	 * Create char device for communication with user-space. The user-space
-	 * process wich want to capture packets should first open this device.
+	 * process wich want to capture packets first opens this device.
 	 * Then, by syscalls on this device it will: 
 	 * - 	get physical adresses of packet buffers for mapping them in its 
-	 * 		virtual memory space 
+	 * 		virtual memory
 	 *
 	 * -	controll packet capturing: start, stop, sleep to wait for packets.
 	 */
@@ -99,41 +104,55 @@
 						device_get_nameunit(dev));
 	if (rm->cdev == NULL) {
 		RINGMAP_ERROR(Can not create char device);
-		contigfree(rm, sizeof(struct ringmap), M_DEVBUF);
+		FREE(rm, M_DEVBUF);
 		return (NULL);
 	}
 
 	/* 
-	 * Tell to ringmap which hardware and driver speciffic functions 
-	 * should it use 
+	 * Set the hardware and driver speciffic functions
 	 */
 	rm->funcs = rf;
 
-	/* Store adapters device structure by ringmap */
+	/* Store interface device structure in ringmap */
 	rm->dev = dev;
 
-	/* Initialize the list of capturing objects */
+	/* 
+	 * Initialize the list of capturing objects. Each object represents the
+	 * thread that capture traffic and its ring.
+	 */
 	SLIST_INIT(&rm->object_list);
 
-	/* Insert ringmap in the global list */
+	/* Insert ringmap structure into the list */
 	SLIST_INSERT_HEAD(&ringmap_list_head, rm, entries);
 
 	/* Init the mutex to protecting our data */
 	RINGMAP_LOCK_INIT(rm, device_get_nameunit(dev));
 
+	/* 
+	 * Set default functions if the generic driver's specific functions are not
+	 * set
+	 */
+	if (rm->funcs->delayed_isr == NULL)
+		rm->funcs->delayed_isr = ringmap_delayed_isr;
+
+	if (rm->funcs->per_packet_iteration == NULL)
+		rm->funcs->per_packet_iteration = per_packet_iteration;
+
+
 	RINGMAP_FUNC_DEBUG(end); 
 
 	/* 
 	 * Return ringmap pointer to the generic driver. Generic driver should
-	 * store the pointer in the adapter structure
+	 * store the pointer in the adapter structure in order to be able to access
+	 * ringmap
 	 */
 	return (rm);	
 }
 
 
 /* 
- * Should be called from driver detach function. It is a little dangerous 
- * place. Probably we shoul protect our data here with mutexes.
+ * Should be called from driver's detach function. It is a little dangerous 
+ * place - probably we shoul protect our code here with locks!!!
  */
 int
 ringmap_detach(device_t dev)
@@ -194,7 +213,7 @@
 
 	rm = cdev2ringmap(cdev);
 	if ( rm == NULL ) {
-		RINGMAP_ERROR(Null pointer to ringmap structure);
+		RINGMAP_ERROR(Could not get the pointer to ringmap structure);
 		return (EIO);
 	}
 
@@ -237,7 +256,7 @@
 	}
 
 	ring->size = SLOTS_NUMBER;
-	ring->pid = td->td_proc->p_pid;
+	ring->pid = td->td_proc->p_pid; /* Unneeded thing. TODO: Replace it with somth more resonable */
 
 	co->ring = ring;
 	co->td = td;
@@ -258,7 +277,7 @@
 
 	/* Init ring-slots with mbufs and packets adrresses */
 	for (i = 0 ; i < SLOTS_NUMBER ; i++) {
-		if (rm->funcs->set_slot(co, i) == -1){
+		if (set_slot(co, i) == -1){
 			RINGMAP_ERROR(Ring initialization failed!);
 
 			contigfree(ring, sizeof(struct ring), M_DEVBUF);
@@ -273,7 +292,6 @@
 
 	/* 
 	 * Insert the capturing object in the single linked list
-	 * the head of the list is in the ringmap structure
 	 */
 	SLIST_INSERT_HEAD(&rm->object_list, co, objects);
 
@@ -324,9 +342,8 @@
 
 
 /* 
- * Callback of ringmap_close() 
- * Free memory allocated for capturing object and remove the 
- * capturing object from the list. 
+ * Callback of ringmap_close() Free memory allocated for capturing object and
+ * remove the capturing object from the list. 
  */
 void 
 clear_capt_object(void * data)
@@ -336,15 +353,12 @@
 
 	RINGMAP_FUNC_DEBUG(start);
 
-	if (data != NULL) {
-		co = (struct capt_object *)data;
+	co = (struct capt_object *)data;
+
+	if (co != NULL) {
 
 		RINGMAP_LOCK(co->rm);
 
-		/* to be completely sure */
-		if (co == NULL) 
-			goto out;
-
 		rm = co->rm;
 #if (__RINGMAP_DEB)
 		printf("[%s] Object to delete:\n", __func__);
@@ -357,12 +371,12 @@
 		FREE(co, M_DEVBUF);
 		data = co = NULL;
 
-		if (rm->open_cnt) {
+		if (rm->open_cnt > 0) {
 			--rm->open_cnt;
 		} else {
 			RINGMAP_WARN(Incorrect value of rm->open_cnt);
 		}
-out: 
+
 		RINGMAP_UNLOCK(rm);
 
 	} else {
@@ -433,15 +447,17 @@
 	struct ringmap *rm = NULL;
 	struct capt_object *co = NULL;
 	vm_paddr_t phys_ring_addr;
+	int error;
 
 	RINGMAP_FUNC_DEBUG(start);
 
 	/* Get pointer to the ringmap structure */
 	rm = cdev2ringmap(cdev);
 
-	if (devfs_get_cdevpriv((void **)&co)) {
-		RINGMAP_ERROR(Can not get capturing object);
-		return(EIO);
+	error = devfs_get_cdevpriv((void **)&co);
+	if (error) {
+		RINGMAP_ERROR(Can not access private data);
+		return(error);
 	} 
 
 	if (co->td != curthread ){
@@ -481,9 +497,10 @@
 	printf("[%s] pid = %d\n", __func__, td->td_proc->p_pid);
 #endif 
 
-	if (devfs_get_cdevpriv((void **)&co)) {
+	err = devfs_get_cdevpriv((void **)&co);
+	if (err != 0) {
 		RINGMAP_IOCTL(Error! Can not get private data!);
-		return (ENODEV);
+		return (err);
 	}
 
 	rm = co->rm;
@@ -496,8 +513,8 @@
 			/* Count how many times we wait for new packets */
 			co->ring->user_wait_kern++;
 
-			/* Set adapter TAIL register */
-			rm->funcs->sync_tail(co);
+			/* Set adapter's TAIL register */
+			rm->funcs->set_tail(co->ring->userrp, co->hw_rx_ring);
 
 #if (RINGMAP_IOCTL_DEB)
 			print_capt_obj(co);
@@ -506,7 +523,7 @@
 			/* 
 			 * 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 :)
+			 * it makes a sence to check if we really must do it 
 			 */
 			while (RING_IS_EMPTY(co->ring)) {
 				RINGMAP_IOCTL(Sleep and wait for new packets);
@@ -514,7 +531,7 @@
 				err = tsleep(co->ring, 
 						(PRI_MAX_ITHD) | PCATCH, "ioctl", 0);
 
-				/* go in user-space by catching signal */
+				/* go back in user-space by catching signal */
 				if (err)
 					goto out;
 			}
@@ -523,7 +540,7 @@
 		/* Synchronize sowftware ring-tail with hardware-ring-tail (RDT) */
 		case IOCTL_SYNC_TAIL:
 			RINGMAP_LOCK(rm);
-			rm->funcs->sync_tail(co);
+			rm->funcs->set_tail(co->ring->userrp, co->hw_rx_ring);
 			RINGMAP_UNLOCK(rm);
 		break;
 
@@ -531,7 +548,7 @@
 			bpf_prog = (struct bpf_program *)data;
 			flen = bpf_prog->bf_len;
 			if (flen > BPF_MAXINSNS) {
-				RINGMAP_ERROR("IOCTL_SETFILTER");
+				RINGMAP_ERROR("bf_len > BPF_MAXINSNS");
 				err = EINVAL;
 				goto out;
 			}
@@ -540,7 +557,7 @@
 			fcode = (struct bpf_insn *)malloc(size, M_BPF, M_WAITOK);
 
 			if (copyin((caddr_t)bpf_prog->bf_insns, (caddr_t)fcode, size) == 0 &&
-				bpf_validate(fcode, (int)flen)) {
+						bpf_validate(fcode, (int)flen)) {
 				co->fcode = (struct bpf_insn *)fcode;
 			} else {
 				RINGMAP_ERROR("Could not set filter");
@@ -548,7 +565,12 @@
 				err = EINVAL;
 				goto out;
 			}
-
+			
+			/* 
+			 * Everything went Ok. Set the filtering function 
+			 * Think about hardware support for packet filtering!
+			 */
+			co->rm->funcs->pkt_filter = ringmap_bpf_filter;
 		break;
 
 		default:
@@ -564,22 +586,102 @@
 }
 
 
-/* Paket filtering */ 
-int 
-ringmap_filter(struct capt_object *co, int slot_num)
+int
+set_slot(struct capt_object *co, unsigned int slot_num)
+{
+	struct ring *ring = co->ring;; 
+	struct ringmap *rm = co->rm;
+
+#if (__RINGMAP_DEB)
+	printf("[%s] Set slot: %d\n", __func__, slot_num);
+#endif
+
+	/* Now if everything is Ok, we can initialize ring pointers */
+	ring->slot[slot_num].mbuf.kern = 
+		(vm_offset_t)rm->funcs->get_mbuf(co->rx_buffers, slot_num);
+	ring->slot[slot_num].mbuf.phys = 
+		(bus_addr_t)vtophys(ring->slot[slot_num].mbuf.kern);
+
+	ring->slot[slot_num].packet.kern = 
+		(vm_offset_t)rm->funcs->get_packet(co->rx_buffers, slot_num);
+	ring->slot[slot_num].packet.phys = 
+		(bus_addr_t)vtophys(ring->slot[slot_num].packet.kern);
+
+	return (0);
+} 
+	
+
+struct capt_object * 
+ringmap_delayed_isr(void *context, struct ringmap *rm)
+{
+	struct capt_object *co = NULL;
+	struct timeval	last_ts;
+
+	RINGMAP_INTR(start);
+
+	RINGMAP_LOCK(rm);
+	/* Do the next steps only if there is capturing process */ 
+	if (rm->open_cnt > 0) {
+
+		/* TODO: do it through our set_timestamp() */
+		getmicrotime(&last_ts);
+
+		SLIST_FOREACH(co, &rm->object_list, objects) {
+			if (co->intr_context == context) {
+#if (RINGMAP_INTR_DEB)
+				PRINT_RING_PTRS(co->ring);
+#endif
+				rm->funcs->set_tail(co->ring->userrp, co->hw_rx_ring);
+				co->ring->last_ts = last_ts;
+				++co->ring->intr_num;
+				break;
+			}
+		}
+	}
+	RINGMAP_UNLOCK(rm);
+
+	RINGMAP_INTR(end);
+
+	return(co);
+}
+
+
+void 
+per_packet_iteration(struct capt_object *co, int slot_num)
+{
+	struct ringmap *rm = co->rm;
+
+	RINGMAP_INTR(start);
+
+	co->ring->slot[slot_num].is_ok = 1;
+	co->ring->slot[slot_num].intr_num = co->ring->intr_num;
+	
+	if (rm->funcs->pkt_filter != NULL)
+		rm->funcs->pkt_filter(co, slot_num);
+
+	co->ring->kernrp = slot_num;
+#ifdef RINGMAP_TIMESTAMP
+	co->ring->slot[slot_num].ts = co->ring->last_ts;
+#endif
+#if (RINGMAP_INTR_DEB)
+	PRINT_SLOT(co->ring, slot_num);
+#endif
+
+	RINGMAP_INTR(end);
+}
+
+
+/* Paket filtering: wrapper around bpf_filter() */ 
+void
+ringmap_bpf_filter(struct capt_object *co, int slot_num)
 {
 	struct mbuf *mb = (struct mbuf *)K_MBUF(co->ring, slot_num);
 	unsigned int pktlen = mb->m_len, slen;
 
 	if (co->fcode != NULL) {
 		slen = bpf_filter(co->fcode, (u_char *)mb, pktlen, 0);
-		if (slen)
-			co->ring->slot[slot_num].filtered = 1;
-		else 
-			co->ring->slot[slot_num].filtered = 0;
+		co->ring->slot[slot_num].filtered = (slen + 1) ? slen:0;
 	}
-
-	return (0);
 }
 
 
@@ -592,11 +694,6 @@
 
 		printf("===  Ring Kernel Addr:0x%X\n", 
 				(unsigned int)co->ring);
-
-		/* Print addr of que only if multiqueue supported */
-		if (co->que != NULL)
-			printf("===  Queue Kernel Addr:0x%X\n\n", 
-					(unsigned int)co->que);
 	} else {
 		RINGMAP_WARN(NULL pointer: capturing object);
 	}
@@ -612,7 +709,6 @@
 		if (rm->dev == dev) 
 			return(rm);
 	}
-
 	return(rm);
 }
 

==== //depot/projects/soc2010/ringmap/current/sys/net/ringmap.h#49 (text+ko) ====

@@ -1,4 +1,5 @@
-#define RING_SAFTY_MARGIN	2
+/* minimal distance between TAIL and HEAD */
+#define RING_SAFTY_MARGIN	1
 
 /* 
  * value for number of descriptors (a.k.a. slots in the ringbuffer)
@@ -7,6 +8,7 @@
 
 /* 
  * Prefix for name of device (for example /dev/ringmap0 will full name) 
+ * currently not used
  */
 #define RINGMAP_DEVICE 		"ringmap"
 
@@ -24,7 +26,7 @@
  */
 #define DEV_ID 	0
 
-/* Enable/Disable Transiv. If 0, then the adapter will only receive pkts */
+/* Enable/Disable tranceive. If 0, then receive only */
 #define RINGMAP_TX_ENABLE 0
  
 /* 1 - enable time stamping in the driver */
@@ -40,10 +42,9 @@
 };
 
 /*
- * This structure represents the ring slot. Each slot contains three 
- * entities: descriptor, mbuf and packet. The descriptore represents 
- * the hardware view of of packet. Mbuf represents the kernel view of 
- * packet. The packet represents the buffer where the packet data placed. 
+ * This structure represents the ring slot. Each slot contains three entities:
+ * mbuf and packet. Mbuf represents the kernel view of packet. The packet
+ * represents the buffer where the packet data is placed. 
  *
  * Each entity is of type 'struct address'. Struct 'address' contains 
  * three addresses: physical-, kernel- and user-address. We need to store 
@@ -51,7 +52,6 @@
  */
 struct ring_slot {
 
-	struct address 	descriptor;
 	struct address 	mbuf;
 	struct address	packet;
 
@@ -85,19 +85,17 @@
 struct ring {
 
 	/*
-	 * kernrp - ring HEAD. Should be changed ONLY in driver. And should be
-	 * synchronized with the adapter-ring-HEAD register. Adapter increments 
-	 * the value in its HEAD-register after storing the incomming packets
-	 * in the RAM. The driver should in the ISR check the value in the 
-	 * adapter-HEAD-register and set this value in kernrp.
+	 * kernrp - ring HEAD. Must be changed ONLY in driver through synchronizing
+	 * with ring-HEAD controller register. Adapter increments the value in its
+	 * HEAD-register after storing the incomming packets in the RAM. The driver 
+	 * is responsible for synchronization kernrp with HEAD-register.
 	 */
 	unsigned int volatile kernrp;
 
 	/* 
-	 * userrp - ring TAIL. Should be incremented by user space software after
-	 * reading the slots with a new received packets. The driver, while 
-	 * executing ISR shoud check the value in userrp and set this value in 
-	 * the adapter-TAIL-register.
+	 * userrp - ring TAIL. Must be incremented only in user space  after
+	 * reading a slot with a new received packet. The driver, while executing
+	 * ISR shoud check userrp and set this value in the adapter-TAIL-register.
 	 */
 	unsigned int volatile userrp;
 
@@ -117,7 +115,7 @@
 	unsigned long long kern_wait_user;
 
 	/* 
-	 * Number of times the user process bumps into the HEAD.
+	 * Number of times the TAIL bumps into the HEAD.
 	 *
 	 * A.K.A. User process has read everything there is to read in the ring.
 	 */
@@ -138,7 +136,7 @@
 	/* TODO: use other ID. Using PID is a wrong way */
 	unsigned int pid;
 
-	/* Array of slots */
+	/* Array of slots (A.K.A packet buffers) */
 	struct ring_slot volatile slot[SLOTS_NUMBER];
 };
 
@@ -266,6 +264,8 @@
 #endif
 
 #ifndef __RINGMAP_DEB
+#define __RINGMAP_DEB 0
+#elif
 #define __RINGMAP_DEB 1
 #endif
 
@@ -346,5 +346,5 @@
 
 
 #ifdef _KERNEL
-#include <net/ringmap_kernel.h>
+#include "ringmap_kernel.h"
 #endif

==== //depot/projects/soc2010/ringmap/current/sys/net/ringmap_kernel.h#19 (text+ko) ====

@@ -5,10 +5,30 @@
 	struct 	thread *td;
 
 	struct 	ring *ring;
-	void 	*que;
+
+	/* 
+	 * Pointers to the structures allocated in the generic driver for accesisng
+	 * hardware registers related to the rx/tx queues associated with our 
+	 * capturing object. 
+	 */
+	void *hw_rx_ring, *hw_tx_ring;
+
+	/*
+	 * Pointer to the arrays allocated in the generic driver for accessing 
+	 * rx/tx buffers and descriptors.
+	 */
+	void *rx_buffers, *tx_buffers, *rx_desc_base, *tx_desc_base;
 
+	/* Packet filtering code. */
 	struct bpf_insn *fcode;
 
+	/* 
+	 * Source of interrupts affecting our capturing object. It can be adapter,
+	 * device or queue structure.
+	 */
+	void *intr_context;
+
+	/* Let's concatenate our objects */
 	SLIST_ENTRY(capt_object) objects;
 };
 
@@ -20,20 +40,19 @@
  * device and driver structures
  */
 struct ringmap {
-	/* Device structure of network adapter */
+	/* Device structure */
 	device_t dev;
 
-	/* Char device for communications between user and kernel spaces */
+	/* Char device for communications between user and ringmap */
 	struct 	cdev 	*cdev;
 
-	/* Number of processes that opened cdev. 
+	/* Number of threads that opened cdev. 
 	 * A.K.A. number of capturing objects  */
 	uint32_t volatile open_cnt;
 	
 	/* Hardware dependent functions */
 	struct ringmap_functions *funcs;
 
-	/* Mutex that should protect the data allocated in the ring */
 	struct mtx	ringmap_mtx;
 
 	/* Head of the list of capturing objects */
@@ -49,59 +68,60 @@
 struct ringmap_functions {
 

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201010172043.o9HKhV62043651>