[openib-general] Fix for possible oops when calling ipoib_neigh_destructor

Ido Bukspan ido at mellanox.co.il
Wed Dec 1 07:29:54 PST 2004


		I have implemented code in order to fix the oops problem,
and it seems like it works fine.
		I still don't have a patch  but here is the pseudo code I
used.
		Please notice that I used a dynamic list (can be organized
in an rb tree as well, as Roland suggested) of the current PATHs which exist
		in the driver (I use it also for the unicast ARP).
		I'm on vacation starting tomorrow but if you want I can work
on a patch when I will come back (two weeks from now).
		Thanks
		-Ido


		The next function will be called from :
ipoib_cleanup_module(void)
		{
			spin_lock_irq(&priv->lock);

			if (list_empty(&priv->path_list))
			{
				// Meaning that the destructor already
destroyed all the entries
				// Nothing to do
				spin_unlock_irq(&priv->lock);
				return;
			}
			spin_unlock_irq(&priv->lock);

			while (TRUE)
			{
				// We will keep checking until the list is
empty.
				spin_lock_irq(&priv->lock);
				
				if (list_empty(&priv->path_list))
				{	//list empty
					spin_unlock_irq(&priv->lock);
					break;
				} else {
					fpath = path_list->next // We keep a
pointer to the first neighbour for future use
					list_for_each_entry_safe(path,
tpath, &priv->path_list, list) {
						// We are cloning all the
neighbours so no destructor could be called 
						// While we are in the
process
						// I know the following is
not well protected but I didn't find something better.
						path->neighbour =
neigh_clone(path->neighbour);
						
						if (&path->neighbour->refcnt
> 1){
						// we check if we are the
only one that hold if.
						// If not we will delete
this AH.	
						list_del(&path->list);
						list_add_tail(&path->list,
&remove_list);
							
						} else {
						// If so the kernel already
start the destructor process and we are backing off.	
	
neigh_release(path->neighbour); 
						}
					}
					spin_unlock_irq(&priv->lock);	
				}
			}
			
			// Set null pointer to the destructor function so
Future called will be called to NULL.
			fpath->neighbour->ops->destructor = NULL;
			// Destroy the AHs
			list_for_each_entry_safe(path, tpath, &remove_list,
list) {
				ib_address_destroy(path->ah);
				//In case  that the module is reloaded, we
erase the path pointer 
				memset(path->neighbour->ha + 24, 0, 8);
				neigh_release(path->neighbour); // For the
cloning
				kfree(path);
			}
			
		}


Ido Bukspan
Mellanox Technologies Ltd.
Phone : (972)-3-6259500 ,Ext 518.
Fax     : (972)-3-5614943
mailto:ido at mellanox.co.il
http://www.mellanox.com

                                    No play No game




More information about the general mailing list