Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 2 Jul 2010 11:27:44 GMT
From:      Alexandre Fiveg <afiveg@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 180408 for review
Message-ID:  <201007021127.o62BRi4i093293@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
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) ====




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