From: Jon M. <jon...@er...> - 2004-04-30 20:43:12
|
Excellent, I think there is ~10-15 linked lists needing conversion, so it is a doable task. I have not been able to do any coding the last days, but I will be back on track on Monday. /Jon Mark Haverkamp wrote: >Jon, > >Here is the first set of linked lists converted to use list head. I ran >the new code using the tipc benchmark with comparable results to the >current version. > >Mark. > >cvs diff -u link.h port.h link.c port.c >Index: link.h >=================================================================== >RCS file: /cvsroot/tipc/source/unstable/net/tipc/link.h,v >retrieving revision 1.10 >diff -u -r1.10 link.h >--- link.h 23 Apr 2004 15:12:05 -0000 1.10 >+++ link.h 30 Apr 2004 15:26:02 -0000 >@@ -105,6 +105,8 @@ > #define PUSH_FINISHED 2 > #define STARTING_EVT 856384768 > >+struct port; >+ > struct link { > tipc_net_addr_t addr; > char name[MAX_LINK_NAME]; >@@ -162,8 +164,7 @@ > uint retransm_queue_head; > uint retransm_queue_size; > struct sk_buff *next_out; >- struct port *first_waiting_port; >- struct port *last_waiting_port; >+ struct list_head waiting_ports; > > /* Fragmentation/defragmentation: */ > uint long_msg_seq_no; >Index: port.h >=================================================================== >RCS file: /cvsroot/tipc/source/unstable/net/tipc/port.h,v >retrieving revision 1.6 >diff -u -r1.6 port.h >--- port.h 11 Mar 2004 01:27:14 -0000 1.6 >+++ port.h 30 Apr 2004 15:26:03 -0000 >@@ -137,12 +137,10 @@ > > struct port { > struct tipc_port publ; >- struct port *next; >- struct port *prev; >+ struct list_head port_list; > uint (*dispatcher) (struct tipc_port*,struct sk_buff *); > void (*wakeup) (struct tipc_port *); >- struct port *next_waiting; >- struct port *prev_waiting; >+ struct list_head wait_list; > struct link *congested_link; > uint waiting_pkts; > uint sent; >@@ -207,8 +205,9 @@ > goto error; > } > err = this->dispatcher(&this->publ,buf); >- if (unlikely(err)) >+ if (unlikely(err)) { > return tipc_reject_msg(buf,err); >+ } > return err; > } > >Index: link.c >=================================================================== >RCS file: /cvsroot/tipc/source/unstable/net/tipc/link.c,v >retrieving revision 1.19 >diff -u -r1.19 link.c >--- link.c 28 Apr 2004 21:56:57 -0000 1.19 >+++ link.c 30 Apr 2004 15:26:03 -0000 >@@ -429,23 +429,12 @@ > spin_lock_bh(&port_lock); > if (!port->wakeup) > goto exit; >- if (port->next_waiting) >- goto exit; >- if (port->prev_waiting) >- goto exit; >- if (this->first_waiting_port == port) >+ if (!list_empty(&port->wait_list)) > goto exit; > port->congested_link = this; > port->publ.congested = 1; > port->waiting_pkts = 1 + sz/link_max_pkt(this); >- if (!this->first_waiting_port) { >- this->first_waiting_port = this->last_waiting_port = port; >- } else { /* Append port to queue */ >- >- port->prev_waiting = this->last_waiting_port; >- this->last_waiting_port->next_waiting = port; >- this->last_waiting_port = port; >- } >+ list_add_tail(&port->wait_list, &this->waiting_ports); > exit: > spin_unlock_bh(&port_lock); > spin_unlock_bh(port->publ.lock); >@@ -455,36 +444,27 @@ > static void > link_wakeup_ports(struct link *this,int all) > { >- struct port *port; >+ struct port *port, *tp; > int win = this->queue_limit[0] - this->out_queue_size; > if (all) > win = 100000; > if (win <= 0) > return; > spin_lock_bh(&port_lock); >- port = this->first_waiting_port; > if (link_congested(this)) > goto exit; >- while (port && (win > 0)) { >- struct port *next = port->next_waiting; >+ list_for_each_entry_safe(port, tp, &this->waiting_ports, wait_list) { >+ if (win <= 0) >+ break; >+ list_del_init(&port->wait_list); > port->congested_link = 0; >- port->prev_waiting = port->next_waiting = 0; > assert(port->wakeup); > spin_lock_bh(port->publ.lock); > port->publ.congested = 0; > port->wakeup(&port->publ); > win =- port->waiting_pkts; >- port = next; > } >- this->first_waiting_port = port; > >- /* >- * Make sure that this port isn't pointing at >- * any port just removed from congestion >- */ >- if (port) { >- port->prev_waiting = 0; >- } > exit: > spin_unlock_bh(&port_lock); > } >@@ -580,6 +560,7 @@ > this->state = RESET_UNKNOWN; > this->next_out_no = 1; > this->bcastlink = NULL; >+ INIT_LIST_HEAD(&this->waiting_ports); > if (LINK_LOG_BUF_SIZE) { > char *buf = k_malloc(LINK_LOG_BUF_SIZE); > printbuf_init(&this->print_buf, buf, LINK_LOG_BUF_SIZE); >@@ -740,7 +721,7 @@ > buf_discard(iter); > iter = next; > } >- if (this->first_waiting_port) >+ if (!list_empty(&this->waiting_ports)) > link_wakeup_ports(this,1); > this->retransm_queue_head = 0; > this->retransm_queue_size = 0; >@@ -1633,7 +1614,7 @@ > } > if (unlikely(this->next_out)) > link_push_queue(this); >- if (unlikely(this->first_waiting_port)) >+ if (unlikely(!list_empty(&this->waiting_ports))) > link_wakeup_ports(this,0); > if (unlikely(++this->unacked_window >= 10)) { > this->stats.sent_acks++; >Index: port.c >=================================================================== >RCS file: /cvsroot/tipc/source/unstable/net/tipc/port.c,v >retrieving revision 1.15 >diff -u -r1.15 port.c >--- port.c 22 Apr 2004 23:28:12 -0000 1.15 >+++ port.c 30 Apr 2004 15:26:03 -0000 >@@ -202,7 +202,7 @@ > spinlock_t port_lock = SPIN_LOCK_UNLOCKED; > static spinlock_t queue_lock = SPIN_LOCK_UNLOCKED; > >-static struct port* ports = 0; >+LIST_HEAD(ports); > static void port_handle_node_down(struct port * this, tipc_net_addr_t); > static void port_abort_self(struct port *,uint err); > static void port_abort_peer(struct port *,uint err); >@@ -290,18 +290,15 @@ > this->last_in_seqno = 41; > this->sent = 1; > this->publ.usr_handle = usr_handle; >- this->next_waiting = this->prev_waiting = 0; >+ INIT_LIST_HEAD(&this->wait_list); > this->congested_link = 0; > this->max_pkt = 1404; /* Ethernet, adjust at connect */ > this->dispatcher = dispatcher; > this->wakeup = wakeup; > this->user_port = 0; > spin_lock_bh(&port_lock); >- this->prev = 0; >- this->next = ports; >- if (this->next) >- this->next->prev = this; >- ports = this; >+ INIT_LIST_HEAD(&this->port_list); >+ list_add_tail(&this->port_list, &ports); > spin_unlock_bh(&port_lock); > return &this->publ; > } >@@ -310,7 +307,6 @@ > tipc_deleteport(const uint ref) > { > struct port *this; >- struct link* cong; > > tipc_withdraw(ref,0); > spin_lock_bh(&port_lock); >@@ -323,34 +319,16 @@ > port_cancel_timer(this); > } > ref_unlock_discard(ref); >- dbg("up = %x, nx = %x, pr = %x, cong %x,nw = %x,lw %x\n", >- this->user_port,this->next,this->prev,this->congested_link, >- this->next_waiting,this->prev_waiting); >- if (this->user_port){ >+ dbg("up = %p, cong %p\n", this->user_port, this->congested_link); >+ if (this->user_port) { > reg_remove_port(this->user_port); > kfree(this->user_port); > } > /* Unlink from port list: */ >- if (this->next) >- this->next->prev = this->prev; >- if (this->prev) >- this->prev->next = this->next; >- else >- ports = this->next; >+ list_del(&this->port_list); > > /* Unlink from link congestion queue, if any: */ >- cong = this->congested_link; >- if (cong){ >- if (this->next_waiting) >- this->next_waiting->prev_waiting = this->prev_waiting; >- else >- cong->last_waiting_port = this->prev_waiting; >- >- if (this->prev_waiting) >- this->prev_waiting->next_waiting = this->next_waiting; >- else >- cong->first_waiting_port = this->next_waiting; >- } >+ list_del(&this->wait_list); > spin_unlock_bh(&port_lock); > kfree(this); > dbg("Deleted port %u\n", ref); >@@ -693,8 +671,7 @@ > struct print_buf b; > printbuf_init(&b,raw,sz); > spin_lock_bh(&port_lock); >- p = ports; >- for (; p; p = p->next) { >+ list_for_each_entry(p, &ports, port_list) { > port_print(p,&b,""); > } > spin_unlock_bh(&port_lock); >@@ -1558,7 +1535,7 @@ > void > port_stop(void) > { >- struct port* p = ports; >+ struct port *p, *tp; > struct sk_buff* b; > spin_lock_bh(&queue_lock); > b = msg_queue_head; >@@ -1569,9 +1546,7 @@ > buf_discard(b); > b = next; > } >- while (p) { >- struct port *next = p->next; >+ list_for_each_entry_safe(p, tp, &ports, port_list) { > tipc_deleteport(p->publ.ref); >- p = next; > } > } > > > |