PERFORCE change 181315 for review
Alexandre Fiveg
afiveg at FreeBSD.org
Thu Jul 22 15:01:31 UTC 2010
http://p4web.freebsd.org/@@181315?ac=10
Change 181315 by afiveg at ringmap-2 on 2010/07/22 15:01:28
Porting ringmap to the 10GbE. ringmap_open(), ringmap_close() work properly. In the function ixgbe_initialize_receive_units() I set in the all RETA-table entries the default queue number. So, all packets will post to the one specific queue. I do this hack in order to make the port to 10G easier: with only one queue works ringmap like by 1Gb adapter.
Affected files ...
.. //depot/projects/soc2010/ringmap/current/sys/dev/ixgbe/ixgbe.c#6 edit
.. //depot/projects/soc2010/ringmap/current/sys/dev/ixgbe/ixgbe.h#5 edit
.. //depot/projects/soc2010/ringmap/current/sys/dev/ixgbe/ringmap_8259.h#4 edit
.. //depot/projects/soc2010/ringmap/current/sys/dev/ixgbe/ringmap_ixgbe.c#5 edit
.. //depot/projects/soc2010/ringmap/current/sys/net/ringmap.c#35 edit
.. //depot/projects/soc2010/ringmap/current/sys/net/ringmap.h#35 edit
.. //depot/projects/soc2010/ringmap/current/sys/net/ringmap_kernel.h#5 edit
.. //depot/projects/soc2010/ringmap/tests/ringmap/close.c#4 edit
.. //depot/projects/soc2010/ringmap/tests/ringmap/ioctl.c#4 edit
.. //depot/projects/soc2010/ringmap/tests/ringmap/main.c#6 edit
.. //depot/projects/soc2010/ringmap/tests/ringmap/mmap.c#6 edit
.. //depot/projects/soc2010/ringmap/tests/ringmap/open.c#6 edit
Differences ...
==== //depot/projects/soc2010/ringmap/current/sys/dev/ixgbe/ixgbe.c#6 (text+ko) ====
@@ -211,7 +211,7 @@
extern int ringmap_attach (device_t, struct ringmap_functions *);
extern int ringmap_detach (device_t);
-extern struct ringmap_functions ringmap_f;
+extern struct ringmap_functions ringmap_8259_f;
#endif
@@ -657,7 +657,7 @@
#ifdef RINGMAP
- ringmap_attach(dev, &ringmap_f);
+ ringmap_attach(dev, &ringmap_8259_f);
#endif
INIT_DEBUGOUT("ixgbe_attach: end");
@@ -1336,7 +1336,7 @@
IXGBE_TX_UNLOCK(txr);
#ifdef RINGMAP
- adapter->rm->funcs->sync_head(adapter->dev);
+ adapter->rm->funcs->sync_head(que);
/* Wakeup threads with not empty rings */
SLIST_FOREACH(co, &adapter->rm->object_list, objects) {
@@ -1346,7 +1346,6 @@
}
#endif
-
if (more) {
taskqueue_enqueue(que->tq, &que->que_task);
return;
@@ -1433,7 +1432,6 @@
#endif
++que->irqs;
-
more_rx = ixgbe_rxeof(que, adapter->rx_process_limit);
IXGBE_TX_LOCK(txr);
@@ -1443,7 +1441,7 @@
more_rx = ixgbe_rxeof(que, adapter->rx_process_limit);
#ifdef RINGMAP
- adapter->rm->funcs->sync_head(adapter->dev);
+ adapter->rm->funcs->sync_head(que);
/* Wakeup threads with not empty rings */
SLIST_FOREACH(co, &adapter->rm->object_list, objects) {
@@ -1453,7 +1451,6 @@
}
#endif
-
/* Do AIM now? */
if (ixgbe_enable_aim == FALSE)
@@ -3930,9 +3927,18 @@
/* Set up the redirection table */
for (i = 0, j = 0; i < 128; i++, j++) {
if (j == adapter->num_queues) j = 0;
+#ifndef RINGMAP
+ reta = (reta << 8) | (j * 0x11);
+#else
+#ifdef DEFAULT_QUEUE
+ reta = (reta << 8) | (DEFAULT_QUEUE * 0x11);
+#else
reta = (reta << 8) | (j * 0x11);
+#endif
+#endif
if ((i & 3) == 3)
IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta);
+
}
/* Now fill our hash function seeds */
==== //depot/projects/soc2010/ringmap/current/sys/dev/ixgbe/ixgbe.h#5 (text+ko) ====
==== //depot/projects/soc2010/ringmap/current/sys/dev/ixgbe/ringmap_8259.h#4 (text+ko) ====
@@ -3,18 +3,13 @@
/* Kernel address of mbuf wich placed in the slot "i" */
-#define GET_MBUF_P(que) \
- (MBUF_AREA(que)[(que)->rxr->me].m_head)
+#define GET_MBUF_P(que, num) \
+ (MBUF_AREA(que)[(num)].m_pack)
/* Kernel address of the packet wich placed in the slot "i" */
-#define GET_PACKET_P(que) \
- (MBUF_AREA(que)[(que)->rxr->me].m_head->m_data)
-
-
-/* Kernel address of the descriptor wich placed in the slot "i" */
-#define GET_DESCRIPTOR_P(que) \
- (&(DESC_AREA(que)[(que)->rxr->me]))
+#define GET_PACKET_P(que, num) \
+ (MBUF_AREA(que)[(num)].m_pack->m_data)
/* Registers access */
@@ -30,7 +25,7 @@
RINGMAP_HW_READ_REG(HW_STRUCT(que), (reg))
#define HW_WRITE_REG(que, reg, val) \
- RINGMAP_HW_READ_REG(HW_STRUCT(que), (reg), (val))
+ RINGMAP_HW_WRITE_REG(HW_STRUCT(que), (reg), (val))
#define RINGMAP_HW_READ_HEAD(que) \
HW_READ_REG((que), HW_RDH(que))
@@ -38,12 +33,11 @@
#define RINGMAP_HW_SYNC_HEAD(que, ring) \
SW_HEAD(ring) = RINGMAP_HW_READ_HEAD(que);
-#define RINGMAP_HW_SYNC_TAIL(que, ring) \
- HW_WRITE_REG((que), HW_RDT(que), SW_TAIL(ring))
-
#define RINGMAP_HW_WRITE_TAIL(que, val) \
HW_WRITE_REG((que), HW_RDT(que), (val))
+#define RINGMAP_HW_SYNC_TAIL(que, ring) \
+ RINGMAP_HW_WRITE_TAIL((que), SW_TAIL(ring))
+
#define RINGMAP_HW_READ_TAIL(que) \
HW_READ_REG((que), HW_RDT(que))
-
==== //depot/projects/soc2010/ringmap/current/sys/dev/ixgbe/ringmap_ixgbe.c#5 (text+ko) ====
@@ -23,14 +23,19 @@
device_t rm_8259_get_device_p(struct cdev *);
void rm_8259_enable_intr(device_t);
void rm_8259_disable_intr(device_t);
-int rm_8259_set_slot(struct ring *, device_t, unsigned int);
+int rm_8259_set_slot(struct ring *, void *, unsigned int);
+int rm_8259_set_queue(struct capt_object *, unsigned int);
void rm_8259_interrupt(void *);
void rm_8259_delayed_interrupt(void *);
int rm_8259_print_ring_pointers(void *);
-void rm_8259_sync_head_tail(device_t);
-void rm_8259_sync_tail(device_t);
-void rm_8259_sync_head(device_t);
+void rm_8259_sync_head_tail(void *);
+void rm_8259_sync_tail(void *);
+void rm_8259_sync_head(void *);
void rm_8259_delayed_interrupt_per_packet(void *, int);
+void rm_8259_disable_receive(void *);
+void rm_8259_enable_receive(void *);
+struct ix_queue * rm_8259_get_free_queue(device_t);
+struct capt_object * get_capt_obj(void *context);
extern devclass_t ixgbe_devclass;
extern void ixgbe_enable_intr(struct adapter *);
@@ -39,7 +44,7 @@
extern void print_capt_obj(struct capt_object *);
-struct ringmap_functions ringmap_f = {
+struct ringmap_functions ringmap_8259_f = {
rm_8259_set_ringmap_to_adapter,
rm_8259_enable_intr,
rm_8259_disable_intr,
@@ -50,6 +55,7 @@
rm_8259_sync_tail,
rm_8259_sync_head,
rm_8259_set_slot,
+ rm_8259_set_queue,
rm_8259_get_ringmap_p,
rm_8259_get_device_p
};
@@ -84,36 +90,65 @@
* 2. SYNC_TAIL: RDT = ring->userrp
*/
void
-rm_8259_sync_head_tail(device_t dev)
+rm_8259_sync_head_tail(void *context)
{
- rm_8259_sync_tail(dev);
- rm_8259_sync_head(dev);
+ rm_8259_sync_tail(context);
+ rm_8259_sync_head(context);
}
void
-rm_8259_sync_tail(device_t dev)
+rm_8259_sync_tail(void *context)
{
- struct adapter *adapter;
- adapter = (struct adapter *)device_get_softc(dev);
+ struct ix_queue *que = (struct ix_queue *)context;
+ struct adapter *adapter = que->adapter;
+ struct capt_object *co = NULL;
-
-
+ RINGMAP_LOCK(adapter->rm);
+ if (adapter->rm->open_cnt) {
+ co = get_capt_obj(que);
+ if (co != NULL) {
+ RINGMAP_HW_SYNC_TAIL(que, co->ring);
+ }
+ }
+ RINGMAP_UNLOCK(adapter->rm);
}
void
-rm_8259_sync_head(device_t dev)
+rm_8259_sync_head(void *context)
{
- struct adapter *adapter;
+ struct ix_queue *que = (struct ix_queue *)context;
+ struct adapter *adapter = que->adapter;
+ struct capt_object *co = NULL;
+ RINGMAP_LOCK(adapter->rm);
+ if (adapter->rm->open_cnt) {
+ co = get_capt_obj(que);
+ if (co != NULL) {
+ RINGMAP_HW_SYNC_HEAD(que, co->ring);
+ } else {
+ RINGMAP_ERROR(There is no capturing object associated with queue);
+ }
+ }
+ RINGMAP_UNLOCK(adapter->rm);
+}
- adapter = (struct adapter *)device_get_softc(dev);
- RINGMAP_LOCK(adapter->rm);
+struct capt_object *
+get_capt_obj(void *queue)
+{
+ struct ix_queue *que = (struct ix_queue *)queue;
+ struct adapter *adapter = que->adapter;
+ struct ringmap *rm = adapter->rm;
+ struct capt_object *co = NULL;
- RINGMAP_UNLOCK(adapter->rm);
+ SLIST_FOREACH(co, &rm->object_list, objects) {
+ if (co->que == que)
+ return (co);
+ }
+ return (co);
}
@@ -138,16 +173,20 @@
struct ix_queue *que = (struct ix_queue *)context;
struct adapter *adapter = (struct adapter *)que->adapter;
struct timeval last_ts;
+ struct capt_object *co = NULL;
RINGMAP_LOCK(adapter->rm);
-
if ( adapter->rm->open_cnt > 0 ) {
-
- adapter->rm->interrupts_counter++;
- getmicrotime(&last_ts);
- rm_8259_sync_tail(adapter->dev);
+ co = get_capt_obj(que);
+ if (co != NULL) {
+ adapter->rm->interrupts_counter++;
+ getmicrotime(&last_ts);
+ co->ring->last_ts = last_ts;
+ rm_8259_sync_tail(context);
+ } else {
+ RINGMAP_ERROR(There is no capturing object associated with queue);
+ }
}
-
RINGMAP_UNLOCK(adapter->rm);
}
@@ -158,6 +197,7 @@
struct ix_queue *que = (struct ix_queue *)context;
struct adapter *adapter = (struct adapter *)que->adapter;
struct ringmap *rm = adapter->rm;;
+ struct capt_object *co = NULL;
RINGMAP_INTR(start);
@@ -166,6 +206,15 @@
#if (RINGMAP_INTR_DEB)
rm_8259_print_ring_pointers(que);
#endif
+ if (adapter->rm->open_cnt) {
+ co = get_capt_obj(que);
+ if (co != NULL) {
+ co->ring->slot[slot_num].intr_num = que->irqs;
+ co->ring->slot[slot_num].ts = co->ring->last_ts;
+ } else {
+ RINGMAP_ERROR(There is no capturing object associated with queue);
+ }
+ }
RINGMAP_UNLOCK(rm);
@@ -174,18 +223,45 @@
int
-rm_8259_set_slot(struct ring *ring, device_t dev, unsigned int slot_num)
+rm_8259_set_slot(struct ring *ring, void *context, unsigned int slot_num)
{
- struct adapter *adapter = NULL;
- adapter = (struct adapter *)device_get_softc(dev);
+ struct ix_queue *que = (struct ix_queue *)context;
#if (__RINGMAP_DEB)
printf("[%s] Set slot: %d\n", __func__, slot_num);
#endif
+ if (que == NULL) {
+ RINGMAP_ERROR(Null pointer to the queue);
+ goto fail;
+ }
+ /* First check pointers */
+//TODO;
+ if (GET_MBUF_P(que, slot_num) == NULL){
+ RINGMAP_ERROR(Pointer to mbuf is NULL);
+ goto fail;
+ }
+ if (GET_PACKET_P(que, slot_num) == NULL){
+ RINGMAP_ERROR(Pointer to packet 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(que, slot_num);
+ ring->slot[slot_num].mbuf.phys =
+ (vm_paddr_t)vtophys(GET_MBUF_P(que, slot_num));
+ ring->slot[slot_num].packet.kern =
+ (vm_offset_t)GET_PACKET_P(que, slot_num);
+ ring->slot[slot_num].packet.phys =
+ (vm_paddr_t)vtophys(GET_PACKET_P(que, slot_num));
+
return (0);
+fail:
+
+ return (-1);
}
@@ -255,6 +331,90 @@
}
+void
+rm_8259_disable_receive(void *context)
+{
+ u32 rxctrl;
+
+ struct ix_queue *que = (struct ix_queue *)context;
+ struct adapter *adapter = (struct adapter *)que->adapter;
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+ IXGBE_WRITE_REG(hw, IXGBE_RXCTRL,
+ rxctrl & ~IXGBE_RXCTRL_RXEN);
+}
+
+
+void
+rm_8259_enable_receive(void *context)
+{
+ u32 rxctrl;
+
+ struct ix_queue *que = (struct ix_queue *)context;
+ struct adapter *adapter = (struct adapter *)que->adapter;
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+ IXGBE_WRITE_REG(hw, IXGBE_RXCTRL,
+ rxctrl | IXGBE_RXCTRL_RXEN);
+}
+
+
+struct ix_queue *
+rm_8259_get_free_queue(device_t dev)
+{
+ struct adapter *adapter;
+ struct ringmap *rm =NULL;
+ struct ix_queue *que = NULL;
+ struct capt_object *co = NULL;
+ int i, j = 1;
+
+ adapter = (struct adapter *)device_get_softc(dev);
+ que = adapter->queues;
+ rm = adapter->rm;
+
+ /*
+ * Look for the queue that is not used by any capturing object (co)
+ */
+ for (i = 0; (i < adapter->num_queues); i++, que++) {
+ j = 0;
+ SLIST_FOREACH(co, &rm->object_list, objects) {
+ j += (co->que == que);
+ }
+ if (j == 0)
+ return (que);
+ }
+
+ return (NULL);
+}
+
+
+int
+rm_8259_set_queue(struct capt_object *co, unsigned int queue_num)
+{
+ device_t dev;
+ struct adapter *adapter;
+ int err = -1;
+
+ if (co->rm != NULL) {
+ dev = co->rm->dev;
+ adapter = (struct adapter *)device_get_softc(dev);
+
+ if (queue_num < adapter->num_queues) {
+ co->que = &adapter->queues[queue_num];
+ err = 0;
+ } else {
+ RINGMAP_ERROR(Wrong queue number);
+ }
+ } else {
+ RINGMAP_ERROR(Capturing object is not associated with ringmap);
+ }
+
+ return (err);
+}
+
+
int
rm_8259_print_ring_pointers(void *context)
{
==== //depot/projects/soc2010/ringmap/current/sys/net/ringmap.c#35 (text+ko) ====
@@ -100,7 +100,7 @@
/* Store adapters device structure */
rm->dev = dev;
- /* Initialize the list of capturing instances */
+ /* Initialize the list of capturing objects */
SLIST_INIT(&rm->object_list);
/* Init the mutex to protecting our data */
@@ -155,7 +155,7 @@
int
ringmap_open(struct cdev *cdev, int flag, int otyp, struct thread *td)
{
- int err = 0, i = 0;
+ int err = 0, i=i;
struct ringmap *rm = NULL;
struct ring *ring = NULL;
struct capt_object *co = NULL;
@@ -163,7 +163,7 @@
RINGMAP_FUNC_DEBUG(start);
#if (__RINGMAP_DEB)
- printf("[%s] pid = %d\n", __func__, td->td_proc->p_pid);
+ printf(RINGMAP_PREFIX"[%s] pid = %d\n", __func__, td->td_proc->p_pid);
#endif
/* a little magic */
@@ -176,13 +176,14 @@
RINGMAP_LOCK(rm);
+ /* TODO: set max number of threads in the ringmap struct as a variable */
if (rm->open_cnt == RINGMAP_MAX_THREADS){
RINGMAP_ERROR(Can not open device!);
err = EIO; goto out;
}
- /* check: the current thread shouldn't open(2) more than one time */
+ /* check: the current thread shouldn't open more than one time */
if (rm->open_cnt) {
SLIST_FOREACH(co, &rm->object_list, objects) {
if (co->td == td) {
@@ -204,18 +205,7 @@
err = EIO; goto out;
}
- for (i = 0 ; i < SLOTS_NUMBER ; i++){
- if (rm->funcs->set_slot(ring, rm->dev, i) == -1){
- RINGMAP_ERROR(Ring initialization failed!);
- contigfree(ring, sizeof(struct ring), M_DEVBUF);
- err = EIO; goto out;
- }
- }
-
- ring->size = SLOTS_NUMBER;
- ring->pid = td->td_proc->p_pid;
-
/*
* create the capturing instance wich will represent
* current thread and packets ring
@@ -227,10 +217,30 @@
err = EIO; goto out;
}
+
+ ring->size = SLOTS_NUMBER;
+ ring->pid = td->td_proc->p_pid;
+
co->ring = ring;
co->td = td;
co->rm = rm;
+ /* The next should be probably done in the ioctl() */
+#ifdef DEFAULT_QUEUE
+ rm->funcs->set_queue(co, DEFAULT_QUEUE);
+ for (i = 0 ; i < SLOTS_NUMBER ; i++){
+ if (rm->funcs->set_slot(ring, co->que, i) == -1){
+ RINGMAP_ERROR(Ring initialization failed!);
+ contigfree(ring, sizeof(struct ring), M_DEVBUF);
+
+ err = EIO; goto out;
+ }
+#if (__RINGMAP_DEB)
+ PRINT_SLOT(ring, i);
+#endif
+ }
+#endif
+
SLIST_INSERT_HEAD(&rm->object_list, co, objects);
/*
@@ -244,15 +254,15 @@
err = EIO; goto out;
}
-
- rm->funcs->sync_head_tail(rm->dev);
+
+ rm->funcs->sync_head_tail(co->que);
+ rm->open_cnt++;
+
#if (__RINGMAP_DEB)
print_capt_obj(co);
PRINT_RING_PTRS(co->ring);
#endif
- rm->open_cnt++;
-
out:
RINGMAP_UNLOCK(rm);
@@ -261,6 +271,8 @@
return (err);
}
+
+
int
ringmap_close(struct cdev *cdev, int flag, int otyp, struct thread *td)
{
@@ -268,7 +280,7 @@
RINGMAP_FUNC_DEBUG(start);
#if (__RINGMAP_DEB)
- printf("[%s] pid = %d\n", __func__, td->td_proc->p_pid);
+ printf(RINGMAP_PREFIX"[%s] pid = %d\n", __func__, td->td_proc->p_pid);
#endif
RINGMAP_FUNC_DEBUG(end);
@@ -424,7 +436,7 @@
case IOCTL_SLEEP_WAIT:
co->ring->user_wait_kern++;
- rm->funcs->sync_head_tail(rm->dev);
+ rm->funcs->sync_head_tail(co->que);
#if (__RINGMAP_DEB)
print_capt_obj(co);
@@ -443,12 +455,12 @@
break;
case IOCTL_SYNC_HEAD_TAIL:
- rm->funcs->sync_head_tail(rm->dev);
+ rm->funcs->sync_head_tail(co->que);
break;
/* Synchronize sowftware ring-tail with hardware-ring-tail (RDT) */
case IOCTL_SYNC_TAIL:
- rm->funcs->sync_tail(rm->dev);
+ rm->funcs->sync_tail(co->que);
break;
default:
@@ -501,10 +513,13 @@
print_capt_obj(struct capt_object *co)
{
if (co != NULL) {
- printf("[%s] co->td->proc->pid: %d\n",
- __func__, co->td->td_proc->p_pid);
+ printf("=== co->td->proc->pid: %d\n",
+ co->td->td_proc->p_pid);
+
+ printf("=== Ring Kernel Addr:0x%X\n",
+ (unsigned int)co->ring);
- printf("[%s] Ring Kernel Addr:0x%X\n",
- __func__, (unsigned int)co->ring);
+ printf("=== Queue Kernel Addr:0x%X\n",
+ (unsigned int)co->que);
}
}
==== //depot/projects/soc2010/ringmap/current/sys/net/ringmap.h#35 (text+ko) ====
@@ -8,6 +8,11 @@
*/
#define RINGMAP_DEVICE "ringmap"
+/*
+ * Default queue number
+ */
+#define DEFAULT_QUEUE 0
+
/*
* Driver works only with device wich has the following device ID. If 0
* then work with all devices that was found and accepted in the "probe"
@@ -23,6 +28,8 @@
/* 1 - enable time stamping in the driver */
#define RINGMAP_TIMESTAMP 1
+/* TODO: should not be as macro */
+#define RINGMAP_MAX_THREADS 8
struct address {
vm_paddr_t phys;
==== //depot/projects/soc2010/ringmap/current/sys/net/ringmap_kernel.h#5 (text+ko) ====
@@ -1,9 +1,11 @@
struct ringmap_functions;
struct capt_object {
- struct thread *td;
- struct ring *ring;
- struct ringmap *rm;
+ struct ringmap *rm;
+ struct thread *td;
+
+ struct ring *ring;
+ void *que;
SLIST_ENTRY(capt_object) objects;
};
@@ -98,14 +100,18 @@
* the value of ring->userrp. Kernel will check this value and set it
* into the hardware TAIL-register.
*/
- void (*sync_head_tail)(device_t);
- void (*sync_tail)(device_t);
- void (*sync_head)(device_t);
+ void (*sync_head_tail)(void *);
+ void (*sync_tail)(void *);
+ void (*sync_head)(void *);
/* Initialize the ring slot */
- int (*set_slot)(struct ring *, device_t, unsigned int);
+ int (*set_slot)(struct ring *, void *, unsigned int);
+
+ /* Associate the capturing objec with a hardware queue */
+ int (*set_queue)(struct capt_object *, unsigned int);
struct ringmap *(*dev_to_ringmap)(device_t);
+
device_t (*cdev_to_dev)(struct cdev *);
};
==== //depot/projects/soc2010/ringmap/tests/ringmap/close.c#4 (text+ko) ====
==== //depot/projects/soc2010/ringmap/tests/ringmap/ioctl.c#4 (text+ko) ====
==== //depot/projects/soc2010/ringmap/tests/ringmap/main.c#6 (text+ko) ====
@@ -23,7 +23,7 @@
exit (1);
}
- rm_mmap(fd);
+ // rm_mmap(fd);
rm_close(fd);
return (0);
==== //depot/projects/soc2010/ringmap/tests/ringmap/mmap.c#6 (text+ko) ====
==== //depot/projects/soc2010/ringmap/tests/ringmap/open.c#6 (text+ko) ====
More information about the p4-projects
mailing list