Re: Rules for calling uio_free
Re: Rules for calling uio_free
- Subject: Re: Rules for calling uio_free
- From: Terry Lambert <email@hidden>
- Date: Thu, 15 Sep 2005 21:30:06 -0700
I suppose you are asking this question because you want to declare
your own uio_t and mess with it, rather than calling uio_create() to
allocate one.
The answer is that this is correct code.
uio_create() allocates memory, which then needs to be freed.
uio_createwithbuffer() fills out the declared buffer argument passed
as argument 5 (usually a stack buffer, like uio_buf in the example
code).
uio_createwithbuffer() is internal SPI, and is used only in specific
circumstances when it is safe to do so. In particular, it's only use
when we know the code which uses it will be recompiled each and every
time the kernel is recompiled.
uio_create() is KPI. We effectively try to guarantee that it will
continue working, no matter what else we do to kernel internals
underlying the implementation of uiomove().
If you look in bsd/kern/kern_subr.c for the implementation of the
functions themselves, you'll see this.
If you are writing a KEXT, you *must* use uio_create(), unless you
want to have to recompile your kext each and every time we ship a
minor number changed kernel.
The reason for this is that the static declaration could change
structure in later versions of the kernel, and as a result, you kext
would break, were you to call uio_createwithbuffer(). If you call
uio_create(), you always get the right-sized one back, and you kext
doesn't start causing mysterious kernel crashes after the next time
your users install a software update.
In other words, act like you expect us to change this structure out
from under you without notice, in the very next software update, and
you won't get your foot shot off when/if it happens.
-- Terry
On Sep 15, 2005, at 4:20 PM, Ron Aldrich wrote:
Folks,
I'm looking through the darwin sources, to determine how to update
those portions of my kext which use uiomove, and I see what appear
to be memory leaks all over the kernel.
In those parts of the kernel that use uio_create to construct a uio
object, they invariably call uio_free to dispose of it (as you
would expect).
However, in those parts of the kernel that use uio_createwithbuffer
to create a uio object, uio_free is NOT called, and the uio object
is leaked.
As an example, from vn.c:
static int
file_io(struct vnode * vp, struct vfs_context * context_p,
enum uio_rw op, char * base, off_t offset, user_ssize_t count,
user_ssize_t * resid)
{
uio_t auio;
int error;
char uio_buf[UIO_SIZEOF(1)];
auio = uio_createwithbuffer(1, offset, UIO_SYSSPACE, op,
&uio_buf[0], sizeof(uio_buf));
uio_addiov(auio, CAST_USER_ADDR_T(base), count);
if (op == UIO_READ)
error = VNOP_READ(vp, auio, IO_SYNC, context_p);
else
error = VNOP_WRITE(vp, auio, IO_SYNC, context_p);
if (resid != NULL) {
*resid = uio_resid(auio);
}
return (error);
}
My question is, is this actually correct code? Or am I right that
it leaks a uio object every time it's called?
Best Regards,
Ron Aldrich
Software Architects, Inc.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
40apple.com
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden