PERFORCE change 180408 for review
Alexandre Fiveg
afiveg at FreeBSD.org
Fri Jul 2 11:27:45 UTC 2010
http://p4web.freebsd.org/@@180408?ac=10
Change 180408 by afiveg at 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) ====
More information about the p4-projects
mailing list