Discussion:
Free a list_head
Fernando Apesteguía
2006-07-11 16:09:38 UTC
Permalink
Hi,

I would like to know how to free a list_head.

I have almost 200 elements and I'm wonder if I must traverse the list for
all the elements and do:

list_for_each(...){
my_entry=list_entry(....)
list_del(my_entry)
kfree(my_entry)
}

Should I do this in this way?

Best regards!
Arjan van de Ven
2006-07-11 16:26:25 UTC
Permalink
Post by Fernando Apesteguía
Hi,
I would like to know how to free a list_head.
I have almost 200 elements and I'm wonder if I must traverse the list
list_for_each(...){
my_entry=list_entry(....)
list_del(my_entry)
kfree(my_entry)
}
Should I do this in this way?
no you should at least use list_for_each_safe() if you're doing this...
(hint: list_for_each caches the next pointer and your code would kfree
this next pointer's memory....)




--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/
Greg KH
2006-07-11 16:21:18 UTC
Permalink
Post by Fernando Apesteguía
Hi,
I would like to know how to free a list_head.
I have almost 200 elements and I'm wonder if I must traverse the list for
list_for_each(...){
my_entry=list_entry(....)
list_del(my_entry)
kfree(my_entry)
}
Should I do this in this way?
No, try this instead:
list_for_each_entry_safe(...) {
list_del(my_entry);
kfree(my_entry);
}

The main point is the _safe usage if you are traversing a list and
deleting items from it at the same time.

Hope this helps,

greg k-h

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/
Fernando Apesteguía
2006-07-13 14:52:47 UTC
Permalink
Hi again :(

I'm facing with some problems with my list. I'll explain in detail:

I have a struct with fields that represent counters and also I have the
list. These two elements are accessed from various points in my code:

The struct and the list are accessed from user context. The counters are
incremented and a new element is added to the list. This is done only when a
certain process is specified by the user. This code looks like this:

if (trace_enabled) { /*Checks if the current process is the user-specified
one*/
process_stats_inc_counter(&my_ps, 1);
attach_to_list(1);
}

Both functions does this work inside a critical section:

down_interruptible(&process_lock);
/*Increment counters*/
up(&process_lock);

down_interruptible(&process_lock);
/*Add element to list*/
up(&process_lock);

When adding the new element to the list, I check if the list is 200 elements
long. If it is, I remove the "last" element. This is the only point where I
remove an element from outside the clearing function.

When the user specifies the new pid I want to clear these data structures.
The counters struct is cleared without problems, but I get an oops when
trying to free the list:

down_interruptible(&process_lock);

/*Setting counters to 0
...
*/

list_for_each_entry_safe(p, my_node, &nodeList, list) {
list_del(&my_node->list);
kfree(my_node);
}

up(&process_lock);

If I comment this loop, the module doesn't crash so I think I'm doing
(again...) something wrong with the list. This function is called from a
procfs callback (where the user specifies the pid to trace).
list_for_each_entry_safe protects the list against removing, but no against
adding, so I tried with the semaphore.

Any Ideas?

... my apologies for the length of the mail
Post by Greg KH
Post by Fernando Apesteguía
Hi,
I would like to know how to free a list_head.
I have almost 200 elements and I'm wonder if I must traverse the list
for
Post by Fernando Apesteguía
list_for_each(...){
my_entry=list_entry(....)
list_del(my_entry)
kfree(my_entry)
}
Should I do this in this way?
list_for_each_entry_safe(...) {
list_del(my_entry);
kfree(my_entry);
}
The main point is the _safe usage if you are traversing a list and
deleting items from it at the same time.
Hope this helps,
greg k-h
Arjan van de Ven
2006-07-13 19:44:22 UTC
Permalink
Post by Fernando Apesteguía
down_interruptible(&process_lock);
note that you're not checking the return value of
down_interruptible() !!
down_interruptible does not always actually take the lock, and it tells
you that via the return value. If you don't check that..... you are in
deep trouble when that happens



--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/
Fernando Apesteguía
2006-07-17 16:59:49 UTC
Permalink
Umm I read linux kernel development and took a look at the example for using
semaphores. But I still have the same problem.

AFAIK, down_interruptible if success, takes the lock, so no other process
would be accessing the list at the same time... If it fails, the process
will sleep and it will be woke up when the up() is performed... so I tried
this:

retval = down_interruptible(&process_lock);

if (!retval) {
/*We need also to initialize the call_list list */
list_for_each_entry_safe(p, my_node, &nodeList, list) {
list_del(&my_node->list);
kfree(my_node);
}

up(&process_lock);
}
return retval;


So if other process is accessing the list, I'll sleep. What happens when I
resume execution of this context? just continue in the next line? or should
I check something more?
Actually, I'm trying to implement a critical section in a simply way, this
is, something like when I did with GTK:

gdk_threads_enter()
/*Critical region*/
gdk_threads_leave()

Maybe you could point me out to a good example on using semaphores inside
the linux kernel
Regards. and thanks in advance
---------- Forwarded message ----------
From: Arjan van de Ven <***@infradead.org>
Date: Jul 13, 2006 9:44 PM
Subject: Re: Free a list_head
Post by Fernando Apesteguía
down_interruptible(&process_lock);
note that you're not checking the return value of
down_interruptible() !!
down_interruptible does not always actually take the lock, and it tells
you that via the return value. If you don't check that..... you are in
deep trouble when that happens
Om.
2006-07-17 17:20:13 UTC
Permalink
Post by Fernando Apesteguía
Umm I read linux kernel development and took a look at the example for using
semaphores. But I still have the same problem.
retval = down_interruptible(&process_lock);
if (!retval) {
/*We need also to initialize the call_list list */
list_for_each_entry_safe(p, my_node, &nodeList, list) {
list_del(&my_node->list);
Change it to &p->list
Read Linux Device drivers 3ed. Page 299.
For reference look into some working, in kernel driver sources (e.g:
linux-2.6.16/drivers/char/drm/drm_context.c)

HTH.
Om.

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/

Daniel Bonekeeper
2006-07-11 16:37:42 UTC
Permalink
Post by Fernando Apesteguía
Hi,
I would like to know how to free a list_head.
I have almost 200 elements and I'm wonder if I must traverse the list for
list_for_each(...){
my_entry=list_entry(....)
list_del(my_entry)
kfree(my_entry)
}
Should I do this in this way?
Best regards!
If your list has dynamically-allocated stuff, you need to free them first.
--
What this world needs is a good five-dollar plasma weapon.

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/
Mohapatra, Hemant
2006-07-11 16:39:31 UTC
Permalink
Post by Fernando Apesteguía
I would like to know how to free a list_head.
I have almost 200 elements and I'm wonder if I must traverse the list for
All list entry removals are O(1). I don't think you need to worry about this too much. You shouldn't have a very large number of list entries within the kernel anyway.

./h



--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/
Om.
2006-07-11 18:23:00 UTC
Permalink
Post by Fernando Apesteguía
Hi,
I would like to know how to free a list_head.
I have almost 200 elements and I'm wonder if I must traverse the list for
list_for_each(...){
my_entry=list_entry(....)
list_del(my_entry)
kfree(my_entry)
}
Don't use it. Use lit_for_each_safe()
From include/linux/list.h,

list_for_each_entry_safe - iterate over list of given type safe
against removal of list entry

HTH,
Om.

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/
Om.
2006-07-11 18:24:12 UTC
Permalink
Post by Om.
Post by Fernando Apesteguía
Hi,
I would like to know how to free a list_head.
I have almost 200 elements and I'm wonder if I must traverse the list for
list_for_each(...){
my_entry=list_entry(....)
list_del(my_entry)
kfree(my_entry)
}
Don't use it. Use lit_for_each_safe()
From include/linux/list.h,
list_for_each_entry_safe - iterate over list of given type safe
against removal of list entry
Free each element's individually kmalloc()-ed pointers first as well.
HTH,
Om.

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/
David H. Lynch Jr.
2006-07-12 07:06:01 UTC
Permalink
If I am writing a network MAC driver, for hardware that has a phy
that is already supported, if I provide the appropriate mdio_read() and
mdio_write() calls to access the phy registers, and setup my config to
include phylib and drivers for my specific phy, what else do I have to
take care of with respect to the phy within my driver ?
--
Dave Lynch DLA Systems
Software Development: Embedded Linux
717.627.3770 ***@dlasys.net http://www.dlasys.net
fax: 1.253.369.9244 Cell: 1.717.587.7774
Over 25 years' experience in platforms, languages, and technologies too numerous to list.

"Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction."
Albert Einstein


--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/
Continue reading on narkive:
Loading...