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...> |