Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Oct 2010 21:21:04 GMT
From:      Alexandre Fiveg <afiveg@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 184942 for review
Message-ID:  <201010202121.o9KLL4wH014331@skunkworks.freebsd.org>

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

Change 184942 by afiveg@cottonmouth on 2010/10/20 21:20:26

	Modifications in the kernel part of ringmap and libpcap that make it possible to use ringmap simultaneously with generic driver functions (protocol stack, (zero)BPF, etc...). At this point more explanation: Earlier ringmap affected the generic driver. The driver was compiled with ringmap and as result the driver was usable only for packet capturing - protocol stack and packet transmission was disabled. Now, compiling the network driver with ringmap code  doesn't affect these functionalities. The protocol stack works as well as without ringmap. !!! But in order to capture with ringmap the interface must be switched in monitor mode !!! In the libpcap the function set_ringmap_flags() is added. Using this function the user-application can choose what capturing functionality has to be used - ringmap or standard packet capturing stack. As before, supported only Intel controller 8254x (if_lem driver).

Affected files ...

.. //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap-bpf.c#19 edit
.. //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap-int.h#19 edit
.. //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap.c#23 edit
.. //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap/pcap.h#3 edit
.. //depot/projects/soc2010/ringmap/current/contrib/libpcap/ringmap_pcap.c#36 edit
.. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/if_lem.c#36 edit
.. //depot/projects/soc2010/ringmap/current/sys/dev/e1000/ringmap_8254.c#37 edit
.. //depot/projects/soc2010/ringmap/current/sys/net/ringmap.c#52 edit
.. //depot/projects/soc2010/ringmap/current/sys/net/ringmap.h#51 edit
.. //depot/projects/soc2010/ringmap/current/sys/net/ringmap_kernel.h#21 edit
.. //depot/projects/soc2010/ringmap/scripts/build_ringmap.sh#34 edit
.. //depot/projects/soc2010/ringmap/scripts/set_ringmap.sh#35 edit
.. //depot/projects/soc2010/ringmap/scripts/tailf_ringmap_msgs.sh#29 edit

Differences ...

==== //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap-bpf.c#19 (text+ko) ====

@@ -165,7 +165,6 @@
 #include <machine/bus.h>
 #include "../../sys/net/ringmap.h"
 extern void	uninit_mmapped_capturing(pcap_t *);
-extern int pcap_read_ringmap(pcap_t *, int, pcap_handler, u_char *);
 #endif 
 
 static int pcap_can_set_rfmon_bpf(pcap_t *p);
@@ -1143,7 +1142,9 @@
 #endif
 
 #ifdef RINGMAP
-	uninit_mmapped_capturing(p);
+	if (p->ringmap_flags == 1){  
+		uninit_mmapped_capturing(p);
+	}
 #endif 
 	if (p->md.must_clear != 0) {
 		/*
@@ -2067,11 +2068,7 @@
 		}
 	}
 
-#ifndef RINGMAP
 	p->read_op = pcap_read_bpf;
-#else 
-	p->read_op = pcap_read_ringmap;
-#endif 
 	p->inject_op = pcap_inject_bpf;
 	p->setfilter_op = pcap_setfilter_bpf;
 	p->setdirection_op = pcap_setdirection_bpf;
@@ -2083,9 +2080,6 @@
 
 	return (status);
  bad:
-#ifdef RINGMAP
-	RINGMAP_FUNC_DEBUG(failed);
-#endif
  	pcap_cleanup_bpf(p);
 	return (status);
 }

==== //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap-int.h#19 (text+ko) ====

@@ -333,6 +333,7 @@
 	struct pcap_pkthdr pcap_header;	/* This is needed for the pcap_next_ex() to work */
 
 #ifdef RINGMAP
+	int ringmap_flags;
 	struct ring *ring;
 #endif
 };

==== //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap.c#23 (text+ko) ====

@@ -77,6 +77,7 @@
 
 extern int init_mmapped_capturing(const char *device, pcap_t *);
 extern void ringmap_setfilter(struct bpf_program *);
+extern int pcap_read_ringmap(pcap_t *, int , pcap_handler , u_char *);
 #endif 
 
 
@@ -255,10 +256,6 @@
 	if (status < 0)
 		goto fail;
 
-#ifdef RINGMAP
-	RINGMAP_FUNC_DEBUG(pcap is allocated);
-#endif
-
 	/*
 	 * Mark this as opened with pcap_open_live(), so that, for
 	 * example, we show the full list of DLT_ values, rather
@@ -275,8 +272,21 @@
 		goto fail;
 
 #ifdef RINGMAP
-	if (init_mmapped_capturing(source, p) < 0){
-		goto fail;
+	/* 
+	 * The setting of ringmap flags should be done in enother function. Why ?
+	 * We want be able to switch on\off ringmap functionality by setting
+	 * ringmap_flags.  In order to do it, the external libpcap application
+	 * should first call the function for setting ringmap_flags. But this
+	 * requires the modification of these application.  Thats why I set
+	 * ringmap_flags staticaly here 
+	 */
+	p->ringmap_flags = set_ringmap_flags(1);
+
+	/* Replace 1 with RINGMAP_ACTIVE macro */
+	if (p->ringmap_flags == 1){
+		if (init_mmapped_capturing(source, p) < 0)
+			goto fail;
+		p->read_op = pcap_read_ringmap;
 	}
 #endif
 
@@ -1012,8 +1022,10 @@
 #ifdef RINGMAP
 	int err = p->setfilter_op(p, fp);
 
-	if (err == 0)
-		ringmap_setfilter(fp);
+	if (p->ringmap_flags == 1){
+		if (err == 0)
+			ringmap_setfilter(fp);
+	}
 		
 	return (err);
 #else 

==== //depot/projects/soc2010/ringmap/current/contrib/libpcap/pcap/pcap.h#3 (text+ko) ====

@@ -339,6 +339,10 @@
 char	*bpf_image(struct bpf_insn *, int);
 void	bpf_dump(struct bpf_program *, int);
 
+#ifdef RINGMAP
+int set_ringmap_flags(int val);
+#endif
+
 #if defined(WIN32)
 
 /*

==== //depot/projects/soc2010/ringmap/current/contrib/libpcap/ringmap_pcap.c#36 (text+ko) ====

@@ -25,8 +25,10 @@
 #include "../../sys/net/ringmap.h"
 
 
+/* TODO: That's dirty! Place the next into the pcap structure */
 /* File descriptor of /dev/iface */
 int ringmap_cdev_fd = -1;
+int ringmap_active_status = 0;
 
 /***	F U N C T I O N S	***/
 int init_mmapped_capturing(const char *device, pcap_t *);
@@ -35,6 +37,18 @@
 void ringmap_setfilter(struct bpf_program *);
 
 
+
+
+int 
+set_ringmap_flags(int val)
+{
+	/* If active status already set do nothing */
+	if (ringmap_active_status == 0)
+		ringmap_active_status = val;
+
+	return (ringmap_active_status);
+}
+
 /********************************************************
  * Open  (/dev/iface) device to communicate with 
  * kernel. Map buffers by calling mmap (/dev/mem, ...)
@@ -70,8 +84,6 @@
 	}
 
 	/**
-	 ** !!! Very important !!!
-	 **
 	 ** Here we map the ring structure into the 
 	 ** memory space of current process.
 	 **/
@@ -89,16 +101,15 @@
 	printf("[%s] Phys addr of ring 0x%X\n", __func__, ring);
 #endif
 
-	tmp_addr = 
-			mmap(	0, 				/* Kernel gives us the address */
-			sizeof(struct ring), 	/* Number of bytes we are mapping */
-			PROT_WRITE|PROT_READ,	/* We want both read and write */
-			MAP_SHARED, 			/* Changes shoud be visible in kernel */
-			devmem_fd, 				/* /dev/mem device */
-			ring);					/* offset = phys addr of ring */
-	if (tmp_addr == MAP_FAILED){
+	tmp_addr = mmap(0,	 		/* Kernel gives us the address */
+		sizeof(struct ring), 	/* Number of bytes we are mapping */
+		PROT_WRITE|PROT_READ,	/* We want both read and write */
+		MAP_SHARED, 			/* Changes shoud be visible in kernel */
+		devmem_fd, 				/* /dev/mem device */
+		ring);					/* offset = phys addr of ring */
+	if (tmp_addr == MAP_FAILED) {
 		RINGMAP_ERROR("Mapping of Ring Pointers structure failed! Exit!");
-		return -1;
+		return (-1);
 	}
 
 	p->ring = (struct ring *)tmp_addr;
@@ -121,20 +132,18 @@
 	/* 
 	 * Mapping mbufs and packet buffers from kern into userspace. 
 	 */
-	for (i = 0; i < SLOTS_NUMBER; i++){
+	for (i = 0; i < SLOTS_NUMBER; i++) {
 
 		/* Map mbuf */
 		memoffset = (off_t)p->ring->slot[i].mbuf.phys;
-		tmp_addr = 
-			mmap (		
-				0, 						/*	System will choose the addrress */
-				sizeof(struct mbuf),	/*	Size of mapped region (mbuf) 	*/
-				PROT_WRITE|PROT_READ,	/*	protection: write & read 		*/
-				MAP_SHARED,				/*	shared maping					*/
-				devmem_fd,				/*	device is /dev/mem				*/
-				memoffset				/*	offset is physical addres 		*/
-			);
-		if (tmp_addr == MAP_FAILED){
+		tmp_addr = mmap (0, 		/*	System will choose the addrress */
+			sizeof(struct mbuf),	/*	Size of mapped region (mbuf) 	*/
+			PROT_WRITE|PROT_READ,	/*	protection: write & read 		*/
+			MAP_SHARED,				/*	shared maping					*/
+			devmem_fd,				/*	device is /dev/mem				*/
+			memoffset				/*	offset is physical addres 		*/
+						);
+		if (tmp_addr == MAP_FAILED) {
 			printf(ERR_PREFIX"[%s] Mapping of mbuf %d failed!\n", 
 								__func__, i);
 			return -1;
@@ -299,12 +308,6 @@
 
 		/* Slot we want to check */
 		curr_slot = R_MODULO( SW_TAIL(ring) + 1 );
-
-		mb = (struct mbuf *)U_MBUF(ring, curr_slot);
-		datap = (caddr_t)U_PACKET(ring, curr_slot);
-		pkthdr.caplen = pkthdr.len = mb->m_len;
-		pkthdr.ts = ring->slot[curr_slot].ts;
-
 		/* 
 		 * ringmap-Driver tell us whether the slot contains 
 		 * a good packet 
@@ -316,6 +319,11 @@
 			goto out;
 		}
 
+		mb = (struct mbuf *)U_MBUF(ring, curr_slot);
+		datap = (caddr_t)U_PACKET(ring, curr_slot);
+		pkthdr.caplen = pkthdr.len = mb->m_len;
+		pkthdr.ts = ring->slot[curr_slot].ts;
+
 		/* Packet filtering */
 		if (p->md.use_bpf) {
 			/* Filtered in Kernel */
@@ -361,8 +369,6 @@
 
 /*
  * Prints HEAD (kern) and TAIL (user) pointers
- * Return Value: 
- * 	-1	-	Error
  */
 int
 print_ring_pointers(pcap_t *p)

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

@@ -81,9 +81,14 @@
 #include <dev/pci/pcireg.h>
 
 #include "e1000_api.h"
+
 #ifdef RINGMAP
 #include <net/ringmap.h>
+extern struct ringmap * ringmap_attach(device_t, struct ringmap_functions *);
+extern int ringmap_detach (struct ringmap *);
+extern struct ringmap_functions ringmap_8254_functions;
 #endif
+
 #include "if_lem.h"
 
 /*********************************************************************
@@ -266,13 +271,6 @@
 #endif /* ~EM_LEGACY_IRQ */
 
 
-#ifdef RINGMAP
-extern struct ringmap * ringmap_attach(device_t, struct ringmap_functions *);
-extern int ringmap_detach (device_t);
-
-extern struct ringmap_functions ringmap_8254_functions;
-#endif 
-
 #ifdef DEVICE_POLLING
 static poll_handler_t lem_poll;
 #endif /* POLLING */
@@ -717,7 +715,7 @@
 	INIT_DEBUGOUT("em_detach: begin");
 
 #ifdef RINGMAP
-	ringmap_detach (dev);
+	ringmap_detach (adapter->rm);
 #endif 
 
 	/* Make sure VLANS are not using driver */
@@ -3498,7 +3496,7 @@
 	}
 
 #ifdef RINGMAP
-		co = adapter->rm->funcs->delayed_isr(adapter, adapter->rm);
+	co = adapter->rm->funcs->delayed_isr(adapter, adapter->rm);
 #endif
 
 	while ((current_desc->status & E1000_RXD_STAT_DD) &&
@@ -3556,17 +3554,18 @@
 
 #ifdef RINGMAP
 			RINGMAP_LOCK(adapter->rm);
-			if ((adapter->rm->open_cnt) && (co != NULL))
+			if ((co != NULL) && (co->ring != NULL))
 				adapter->rm->funcs->per_packet_iteration(co, i);
-			RINGMAP_UNLOCK(adapter->rm);
+			else {
 #endif
 
-#ifndef RINGMAP
-/* RINGMAP: Do not allocate memory for new mbufs and packets. Work in ring */
 			if (lem_get_buf(adapter, i) != 0) {
 				ifp->if_iqdrops++;
 				goto discard;
 			}
+#ifdef RINGMAP
+			}
+			RINGMAP_UNLOCK(adapter->rm);
 #endif
 			/* Assign correct length to the current fragment */
 			mp->m_len = len;
@@ -3625,9 +3624,7 @@
 			}
 		} else {
 			ifp->if_ierrors++;
-#ifndef RINGMAP
 discard:
-#endif
 			/* Reuse loaded DMA map and just update mbuf chain */
 			mp = adapter->rx_buffer_area[i].m_head;
 			mp->m_len = mp->m_pkthdr.len = MCLBYTES;
@@ -3656,11 +3653,18 @@
 		if (m != NULL) {
 			adapter->next_rx_desc_to_check = i;
 
-#ifndef RINGMAP
-/* Do not send packet to the IP-stack */
+#ifdef RINGMAP
+		RINGMAP_LOCK(adapter->rm);
+			if ((co == NULL) || (co->ring == NULL)) {
+#endif 
+
 			EM_RX_UNLOCK(adapter);
 			(*ifp->if_input)(ifp, m);
 			EM_RX_LOCK(adapter);
+
+#ifdef RINGMAP
+			}
+		RINGMAP_UNLOCK(adapter->rm);
 #endif 
 			rx_sent++;
 			i = adapter->next_rx_desc_to_check;
@@ -3670,7 +3674,7 @@
 
 #ifdef RINGMAP
 	RINGMAP_LOCK(adapter->rm);
-		if ((co != NULL) && (RING_NOT_EMPTY(co->ring)))
+		if ((co != NULL) && (co->ring != NULL) && (RING_NOT_EMPTY(co->ring)))
 			wakeup(co->ring);
 	RINGMAP_UNLOCK(adapter->rm);
 #endif 
@@ -3682,8 +3686,14 @@
 		i = adapter->num_rx_desc - 1;
 
 	/* 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);
+#ifdef RINGMAP
+	RINGMAP_LOCK(adapter->rm);
+	if ((co == NULL) || (co->ring == NULL)) {
+#endif 
+		E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i);
+#ifdef RINGMAP
+	}
+	RINGMAP_UNLOCK(adapter->rm);
 #endif 
 
 	EM_RX_UNLOCK(adapter);

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

@@ -2,16 +2,11 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/conf.h>
-#include <sys/queue.h>
-#include <sys/taskqueue.h>
 
-#include <machine/bus.h>
-
 #include <net/if.h>
 #include <net/if_var.h>
 #include <net/if_types.h>
 #include <net/if_media.h>
-#include <net/bpf.h>
 
 #include <net/ringmap.h>
 
@@ -26,7 +21,12 @@
 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);
 int rm_8245_get_queuesnum(void);
+void rm_8254_receive_disable (struct ringmap *rm);
+void rm_8254_receive_enable (struct ringmap *rm);
+void rm_8254_intr_disable (struct ringmap *rm);
+void rm_8254_intr_enable (struct ringmap *rm);
 
+
 extern devclass_t em_devclass;
 
 
@@ -42,9 +42,65 @@
 	.set_queue = rm_8254_set_queue,
 	.pkt_filter = NULL,
 	.get_queuesnum = rm_8245_get_queuesnum,
+	.set_timestamp = NULL,
+	.receive_disable = rm_8254_receive_disable,
+	.receive_enable = rm_8254_receive_enable,
+	.intr_disable = rm_8254_intr_disable,
+	.intr_enable = rm_8254_intr_enable,
 };
 
 
+void
+rm_8254_intr_disable (struct ringmap *rm)
+{
+	struct adapter *adapter =(struct adapter *)device_get_softc(rm->dev);
+	struct e1000_hw *hw = &adapter->hw;
+
+	if (adapter->msix)
+		E1000_WRITE_REG(hw, EM_EIAC, 0);
+	E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
+}
+
+
+void
+rm_8254_intr_enable (struct ringmap *rm)
+{
+	struct adapter *adapter =(struct adapter *)device_get_softc(rm->dev);
+	struct e1000_hw *hw = &adapter->hw;
+	u32 ims_mask = IMS_ENABLE_MASK;
+
+	if (adapter->msix) {
+		E1000_WRITE_REG(hw, EM_EIAC, EM_MSIX_MASK);
+		ims_mask |= EM_MSIX_MASK;
+	} 
+	E1000_WRITE_REG(hw, E1000_IMS, ims_mask);
+}
+
+
+void
+rm_8254_receive_disable (struct ringmap *rm)
+{
+	struct adapter *adapter; 
+	u32	rctl;
+
+	adapter = (struct adapter *)device_get_softc(rm->dev);
+	rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
+	E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl & ~E1000_RCTL_EN);
+}
+
+
+void
+rm_8254_receive_enable (struct ringmap *rm)
+{
+	struct adapter *adapter; 
+	u32	rctl;
+
+	adapter = (struct adapter *)device_get_softc(rm->dev);
+	rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
+	E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl | E1000_RCTL_EN);
+}
+
+
 struct mbuf * 
 rm_8254_get_mbuf(void *buffer_area, unsigned int num)
 {

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

@@ -39,16 +39,16 @@
 #include "ringmap.h"
 
 struct ringmap * ringmap_attach (device_t, struct ringmap_functions *);
-int ringmap_detach (device_t);
+int ringmap_detach (struct ringmap *rm);
 void ringmap_close_cb (void *data);
 void clear_capt_object(void *);
-void print_capt_obj(struct capt_object *);
 struct ringmap * cdev2ringmap(struct cdev *);
 struct ringmap * dev2ringmap(device_t);
 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);
+void ringmap_timestamp(struct ring_slot *slot, struct timeval *ts);
 
 d_open_t	ringmap_open;
 d_close_t	ringmap_close;
@@ -71,9 +71,10 @@
 
 
 /*
- * 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. Also default ringmap functions are set.
+ * The function should be called from the attach function of generic network
+ * driver.  Here the ringmap structure is allocated and the character special
+ * device for the communication with user is created. Also default ringmap
+ * functions are set.
  */
 struct ringmap *
 ringmap_attach(device_t dev, struct ringmap_functions *rf) 
@@ -91,26 +92,23 @@
 	}
 
 	/* 
-	 * Create char device for communication with user-space. The user-space
-	 * process wich want to capture packets first opens this device.
+	 * Create character special device for communication with user-space. The
+	 * user-space 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
-	 *
 	 * -	controll packet capturing: start, stop, sleep to wait for packets.
 	 */
 	rm->cdev = make_dev(&ringmap_devsw, device_get_unit(dev),
 						UID_ROOT, GID_WHEEL, 0666, 
 						device_get_nameunit(dev));
 	if (rm->cdev == NULL) {
-		RINGMAP_ERROR(Can not create char device);
+		RINGMAP_ERROR(Can not create character device);
 		FREE(rm, M_DEVBUF);
 		return (NULL);
 	}
 
-	/* 
-	 * Set the hardware and driver speciffic functions
-	 */
+	/* Set the hardware and driver speciffic functions */
 	rm->funcs = rf;
 
 	/* Store interface device structure in ringmap */
@@ -130,7 +128,7 @@
 
 	/* 
 	 * Set default functions if the generic driver's specific functions are not
-	 * set
+	 * set.
 	 */
 	if (rm->funcs->delayed_isr == NULL)
 		rm->funcs->delayed_isr = ringmap_delayed_isr;
@@ -138,31 +136,30 @@
 	if (rm->funcs->per_packet_iteration == NULL)
 		rm->funcs->per_packet_iteration = per_packet_iteration;
 
+	if (rm->funcs->set_timestamp == NULL)
+		rm->funcs->set_timestamp = ringmap_timestamp;
 
 	RINGMAP_FUNC_DEBUG(end); 
 
 	/* 
 	 * Return ringmap pointer to the generic driver. Generic driver should
 	 * store the pointer in the adapter structure in order to be able to access
-	 * ringmap
+	 * ringmap.
 	 */
 	return (rm);	
 } 
 
 
 /* 
- * Should be called from driver's detach function. It is a little dangerous 
- * place - probably we shoul protect our code here with locks!!!
+ * Should be called from driver's detach function. 
  */
 int
-ringmap_detach(device_t dev)
+ringmap_detach(struct ringmap *rm)
 {
-	struct ringmap *rm = NULL;
 	struct capt_object *co = NULL;
 
 	RINGMAP_FUNC_DEBUG(start);
 	
-	rm = dev2ringmap(dev);
 	if (rm == NULL) {
 		RINGMAP_WARN(Can not get pointer to ringmap structure);
 		return (-1);
@@ -185,11 +182,9 @@
 
 	/* And remove ringmap from global list */
 	SLIST_REMOVE(&ringmap_list_head, rm, ringmap, entries);
-
 	RINGMAP_UNLOCK(rm);
 
 	RINGMAP_LOCK_DESTROY(rm);
-	
 	FREE(rm, M_DEVBUF);
 
 	RINGMAP_FUNC_DEBUG(end);
@@ -198,12 +193,11 @@
 }
 
 
-/******************************************************************
- * This func is called as result of open(2). Here we allocate 
- * the memory for the new ring and capt_object structure (so called 
- * capturing object). Capturing object represents the thread with 
- * its ring.
- ******************************************************************/
+/*
+ * This function is called as result of open(2). Here we allocate the memory
+ * for the new ring and capt_object structure (so called capturing object).
+ * Capturing object represents a thread with its ring.
+ */
 int
 ringmap_open(struct cdev *cdev, int flag, int otyp, struct thread *td)
 {
@@ -217,7 +211,6 @@
 #if (__RINGMAP_DEB)
 	printf(RINGMAP_PREFIX"[%s] pid = %d\n", __func__, td->td_proc->p_pid);
 #endif 
-
 	rm = cdev2ringmap(cdev);
 	if ( rm == NULL ) {
 		RINGMAP_ERROR(Could not get the pointer to ringmap structure);
@@ -232,6 +225,11 @@
 		err = EIO; goto out;
 	}
 
+	/* First stop receive and interupts while we allocate our data */
+	rm->funcs->receive_disable(rm);
+	rm->funcs->intr_disable(rm);
+	// pause("wait", hz); 
+
 	/* Only ONE open() per thread */
 	SLIST_FOREACH(co, &rm->object_list, objects) {
 		if (co->td == td) {
@@ -250,28 +248,22 @@
 		RINGMAP_ERROR(Can not allocate space for ring);
 		err = EIO; goto out;
 	}
+	ring->size = SLOTS_NUMBER;
 
 	/* 
-	 * create the capturing object wich will represent 
-	 * current thread and packets ring 
+	 * create the capturing object wich will represent current thread and
+	 * its packets ring 
 	 */
 	MALLOC(co, struct capt_object *, 
 			sizeof(struct capt_object), M_DEVBUF, (M_ZERO | M_WAITOK));
-	if ( co == NULL ){
+	if ( co == NULL ) {
 		contigfree(ring, sizeof(struct ring), M_DEVBUF);
 		err = EIO; goto out;
 	}
-
-	ring->size = SLOTS_NUMBER;
-
 	co->ring = ring;
 	co->td = td;
 	co->rm = rm;
 
-
-	/* 
-	 * Insert the capturing object in the single linked list
-	 */
 	SLIST_INSERT_HEAD(&rm->object_list, co, objects);
 
 	/* 
@@ -280,25 +272,19 @@
 	 */
 	if (devfs_set_cdevpriv((void *)co, clear_capt_object)) {
 		RINGMAP_ERROR(Can not set private data!);
-
 		contigfree(ring, sizeof(struct ring), M_DEVBUF);
 		FREE(co, M_DEVBUF);
-
 		err = EIO; goto out;
 	}
 
 	++rm->open_cnt;
+	CAPT_OBJECT_DEB(co);
+out:
+	rm->funcs->intr_enable(rm);
+	rm->funcs->receive_enable(rm);
 
-#if (__RINGMAP_DEB)
-	print_capt_obj(co);
-	PRINT_RING_PTRS(co->ring); 
-#endif
-
-out:
 	RINGMAP_UNLOCK(rm);
-
 	RINGMAP_FUNC_DEBUG(end);
-
 	return (err);
 }
 
@@ -335,27 +321,20 @@
 	co = (struct capt_object *)data;
 
 	RINGMAP_LOCK(co->rm);
-	if (co != NULL) {
-		rm = co->rm;
-#if (__RINGMAP_DEB)
-		printf("[%s] Object to delete:\n", __func__);
-		print_capt_obj(co);
-#endif 
-		if (co->ring != NULL)
-			contigfree(co->ring, sizeof(struct ring), M_DEVBUF);
+
+	CAPT_OBJECT_DEB(co);
+
+	rm = co->rm;
+	contigfree(co->ring, sizeof(struct ring), M_DEVBUF);
+	co->ring = NULL;
 
-		SLIST_REMOVE(&rm->object_list, co, capt_object, objects);
-		FREE(co, M_DEVBUF);
-		data = co = NULL;
+	SLIST_REMOVE(&rm->object_list, co, capt_object, objects);
+	FREE(co, M_DEVBUF);
 
-		if (rm->open_cnt > 0) {
-			--rm->open_cnt;
-		} else {
-			RINGMAP_WARN(Incorrect value of rm->open_cnt);
-		}
-	} else {
-		RINGMAP_FUNC_DEBUG(NULL pointer to the capturing object!);
-	}
+	if (rm->open_cnt > 0)
+		--rm->open_cnt;
+	 else 
+		RINGMAP_WARN(Incorrect value of rm->open_cnt);
 	RINGMAP_UNLOCK(rm);
 	
 	RINGMAP_FUNC_DEBUG(end);
@@ -369,17 +348,12 @@
 {
 	struct ringmap *rm = NULL;
 	struct capt_object *co = NULL;
-
 	vm_object_t obj;
 	vm_map_entry_t  entry;
     vm_pindex_t pindex;
     vm_prot_t prot;
     boolean_t wired;
 
-
-	RINGMAP_FUNC_DEBUG(start);
-
-
 	rm = cdev2ringmap(cdev);
 	if ( rm == NULL ) {
 		RINGMAP_ERROR(Null pointer to ringmap structure);
@@ -388,12 +362,12 @@
 	}
 
 	SLIST_FOREACH(co, &rm->object_list, objects) {
-		if (co->td == curthread){
+		if (co->td == curthread) {
 			break;
 		}
 	}
 
-	if ((co == NULL) || (co->ring == NULL)){
+	if ((co == NULL) || (co->ring == NULL)) {
 		RINGMAP_ERROR(Null pointer);
 		return (EIO);
 	}
@@ -402,7 +376,7 @@
 			      &entry, &obj, &pindex, &prot, &wired);
 	vm_map_lookup_done(kmem_map, entry);
 
-	if (obj == kmem_object){
+	if (obj == kmem_object) {
 		RINGMAP_ERROR(Got kmem_object);
 	} else {
 		RINGMAP_FUNC_DEBUG(Got other obj);
@@ -410,12 +384,15 @@
 
 	object = &obj;
 
-	RINGMAP_FUNC_DEBUG(start);
-
 	return (0);
 }
 
 
+/*
+ * Tells usre the physical addres of ring. User process will 
+ * use this addres in order to map the buffer in its address 
+ * space.
+ */
 int 
 ringmap_read(struct cdev *cdev, struct uio *uio, int ioflag)
 {
@@ -432,21 +409,12 @@
 	error = devfs_get_cdevpriv((void **)&co);
 	if (error) {
 		RINGMAP_ERROR(Can not access private data);
-		return(error);
+		return (error);
 	} 
 
-	if (co->td != curthread ){
-		RINGMAP_ERROR(Wrong capturing object!);
-		return(EIO);
-	}
+	CAPT_OBJECT_DEB(co);
 
 	phys_ring_addr = vtophys(co->ring);
-
-#if (__RINGMAP_DEB)
-	print_capt_obj(co);
-	PRINT_RING_PTRS(co->ring);
-#endif
-
 	uiomove(&phys_ring_addr, sizeof(phys_ring_addr), uio);
 
 	RINGMAP_FUNC_DEBUG(end);
@@ -484,34 +452,30 @@
 
 		/* Sleep and wait for new packets */
 		case IOCTL_SLEEP_WAIT:
+			/* Set the new value into the adapter's TAIL register */
+			rm->funcs->set_tail(co->ring->userrp, co->hw_rx_ring);
 
-			/* Count how many times we wait for new packets */
-			co->ring->user_wait_kern++;
-
-			/* Set adapter's TAIL register */
-			rm->funcs->set_tail(co->ring->userrp, co->hw_rx_ring);
+			CAPT_OBJECT_DEB(co);
 
-#if (RINGMAP_IOCTL_DEB)
-			print_capt_obj(co);
-			PRINT_RING_PTRS(co->ring);
-#endif
 			/* 
-			 * 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 
+			 * Before we are going to sleep 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);
 
+				/* Count how many times we wait for new packets */
+				co->ring->user_wait_kern++;
+
 				err = tsleep(co->ring, 
 						(PRI_MAX_ITHD) | PCATCH, "ioctl", 0);
-
-				/* go back in user-space by catching signal */
+				/* go back into user-space by catching signal */
 				if (err)
 					goto out;
 			}
 		break;
 
+
 		/* Synchronize sowftware ring-tail with hardware-ring-tail (RDT) */
 		case IOCTL_SYNC_TAIL:
 			RINGMAP_LOCK(rm);
@@ -519,6 +483,7 @@
 			RINGMAP_UNLOCK(rm);
 		break;
 
+
 		case IOCTL_SETFILTER:
 			bpf_prog = (struct bpf_program *)data;
 			flen = bpf_prog->bf_len;
@@ -527,7 +492,6 @@
 				err = EINVAL;
 				goto out;
 			}
-
 			size = flen * sizeof(*bpf_prog->bf_insns);
 			fcode = (struct bpf_insn *)malloc(size, M_BPF, M_WAITOK);
 
@@ -540,7 +504,6 @@
 				err = EINVAL;
 				goto out;
 			}
-			
 			/* 
 			 * Everything went Ok. Set the filtering function 
 			 * Think about hardware support for packet filtering!
@@ -548,34 +511,41 @@
 			co->rm->funcs->pkt_filter = ringmap_bpf_filter;
 		break;
 
-		/* Tell to user how many queues we have */
+
+		/* Tell user how many queues we have */
 		case IOCTL_GETQUEUE_NUM:
 			qn = rm->funcs->get_queuesnum();
 			*(int *)data = qn;
 		break;
 
+
 		/* Associate the ring/queue with the capturing object */
 		case IOCTL_ATTACH_RING:
+			/* First stop receive and interupts while we allocate our data */
+			rm->funcs->receive_disable(rm);
+			rm->funcs->intr_disable(rm);
+
 			qn = *(int *)data;
-
 			/* Associate the capturing object with a queue */
 			if (rm->funcs->set_queue(co, qn) == -1) {
 				RINGMAP_ERROR(Queue attachment failed!);
 				err = EINVAL;
-				goto out;
+				goto xxx;
 			}
-
 			/* Init ring-slots with mbufs and packets adrresses */
 			for (i = 0 ; i < SLOTS_NUMBER ; i++) {
-				if (set_slot(co, i) == -1){
+				if (set_slot(co, i) == -1) {
 					RINGMAP_ERROR(Ring initialization failed!);
 					err = EINVAL; 
-					goto out;
+					goto xxx;
 				}
 #if (__RINGMAP_DEB)
 				PRINT_SLOT(co->ring, i);
 #endif
 			}
+xxx:		
+			rm->funcs->intr_enable(rm);
+			rm->funcs->receive_enable(rm);
 		break;
 		
 
@@ -585,9 +555,7 @@
 	}
  
 out: 
-
 	RINGMAP_IOCTL(end);
- 
 	return (err);
 }
 
@@ -624,24 +592,20 @@
 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);

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



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