From: Mark H. <ma...@os...> - 2004-04-30 16:21:37
|
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; } } -- Mark Haverkamp <ma...@os...> |
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; > } > } > > > |