Skip to contentSkip to conversation

memcpy failure

Linux-ia64 Christian Cotte-Barrot 6 participants 14 messages Nov 14, 2002 – Nov 15, 2002

lore
Share & tools
lore
#0 lore raw
Quoted 5 lines · Kenneth W

The retrun value for memcpy doesn't follow the user space memcpy exactly. kernel memcpy always return 0.
- Ken

But memcpy from memcpy.S is returning a pointer to dest area. That would lead to quasi non-portable code when the return from memcopy is correctly checked depending on which memcopy function is addressed. But BTW, is it meaningful to take into account a return code that is always the same and which value is known in advance ? Does memcpy suppose to failed in some cases ?

#1 lore raw
Quoted 6 lines · Christian Cotte-Barrot

But memcpy from memcpy.S is returning a pointer to dest area. That would lead to quasi non-portable code when the return from memcopy is correctly checked depending on which memcopy function is addressed. But BTW, is it meaningful to take into account a return code that is always the same and which value is known in advance ? Does memcpy suppose to failed in some cases ?

no, memcpy cannot fail (you get a SIGSEGV in userspace or an MCA in kernel space). checking the return value is meaningless.

Signature · 1 line
Revolutions do not require corporate support.
#2 lore raw
In reply to Christian Cotte-Barrot

I sometimes prefer a routine to return a pointer, even if the pointer is known in advance. This way you can set a pointer in the same statement that does the copy, e.g.:

	ptr = memcpy(malloc(100), buffer, 100);

rather than:

	ptr = malloc(100);
	memcpy(ptr, buffer, 100);

This is just a stylistic issue, I like to remove lines of code whenever possible.

PS: I would never actually do this code example, using a malloc without checking the result is wrong, but you get the idea.

Quoted 18 lines · Christian Cotte-Barrot
Quoted 5 lines · Kenneth W

The retrun value for memcpy doesn't follow the user space memcpy exactly. kernel memcpy always return 0.
- Ken

But memcpy from memcpy.S is returning a pointer to dest area. That would lead to quasi non-portable code when the return from memcopy is correctly checked depending on which memcopy function is addressed. But BTW, is it meaningful to take into account a return code that is always the same and which value is known in advance ? Does memcpy suppose to failed in some cases ?

_______________________________________________
Linux-IA64 mailing list
[email protected]
http://lists.linuxia64.org/lists/listinfo/linux-ia64

Signature · 3 lines
Don Dugger
"Censeo Toto nos in Kansa esse decisse." - D. Gale
[email protected]
#3 lore raw
In reply to Christian Cotte-Barrot

David,

I was thinking along the same line as returning void for memcpy. And that is what implemented in memcpy_mck.S. r8 is initialized to zero in the code path mainly for copy_user.

I suppose I should follow the convention since everyone except me expect memcpy to return dest pointer and actually use the return value ;-) I can work on that although I need to shuffle some instruction around to avoid expand the code size and worsen the copy throughput.

- Ken

-----Original Message-----
From: David Mosberger [mailto:[email protected]]
Sent: Wednesday, November 13, 2002 9:52 PM
To: Chen, Kenneth W
Cc: Christian Cotte-Barrot; David Mosberger; Stephane Eranian
Subject: RE: memcpy failure

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line · Kenneth W

Ken> The retrun value for memcpy doesn't follow the user space Ken> memcpy exactly. kernel memcpy always return 0.

Why are you saying this? As far as I know, the kernel memcpy() is expected to return the (initial) destination address. Perhaps you're thinking of copy_user()?

(If it was up to me, memcpy() would be returning void...).

	--david
#4 lore raw
In reply to Christian Cotte-Barrot
Quoted 10 lines
Quoted 7 lines · Christian Cotte-Barrot

But memcpy from memcpy.S is returning a pointer to dest area. That would lead to quasi non-portable code when the return from memcopy is correctly checked depending on which memcopy function is addressed. But BTW, is it meaningful to take into account a return code that is always the same and which value is known in advance ? Does memcpy suppose to failed in some cases ?

no, memcpy cannot fail (you get a SIGSEGV in userspace or an MCA in kernel space). checking the return value is meaningless.

That's what I feel as well that it is kind of silly to return something that the caller already has. BUt then, I'm not here to judge the specification ;-)

Anyhow, the fix is fairly easy and won't affect the code size as well as the copy throughput, I should have a patch ready shortly to make everyone happy!

- Ken

#5 lore raw
In reply to Christian Cotte-Barrot
Quoted 11 lines · Matthew Wilcox
Quoted 6 lines · Christian Cotte-Barrot

But memcpy from memcpy.S is returning a pointer to dest area. That would lead to quasi non-portable code when the return from memcopy is correctly checked depending on which memcopy function is addressed. But BTW, is it meaningful to take into account a return code that is always the same and which value is known in advance ? Does memcpy suppose to failed in some cases ?

no, memcpy cannot fail (you get a SIGSEGV in userspace or an MCA in kernel space). checking the return value is meaningless.

Quoted 9 lines

--
Revolutions do not require corporate support.

_______________________________________________
Linux-IA64 mailing list
[email protected]
http://lists.linuxia64.org/lists/listinfo/linux-ia64

Aren't all these routines suppose to return -EFAULT if a fault occurs?

- Mario.

#6 lore raw
In reply to Christian Cotte-Barrot
Quoted 1 line · Mario Smarduch

Aren't all these routines suppose to return -EFAULT if a fault occurs?

No. Did you go to the Richard B Johnson school of C programming?

Signature · 1 line
Revolutions do not require corporate support.
#7 lore raw
In reply to Christian Cotte-Barrot
Quoted 7 lines · Matthew Wilcox
Quoted 1 line · Mario Smarduch

Aren't all these routines suppose to return -EFAULT if a fault occurs?

No. Did you go to the Richard B Johnson school of C programming?

--
Revolutions do not require corporate support.

I'm referring to page faults and what handle_exception() does - regs->r8 -EFAULT

#8 lore raw
In reply to Christian Cotte-Barrot
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line · Mario Smarduch

Mario> I'm referring to page faults and what handle_exception() does Mario> - regs->r8 = -EFAULT

In the case of memcpy(), there are no exception regions ("handlers"), so handle_exception() won't do anything. copy_user() is different that way.

	--david
#9 lore raw
In reply to Christian Cotte-Barrot

Here is the patch that I promised.

Bjorn, would you please apply it to the 2.4 tree? and David, would you please apply it to the 2.5 tree?

Thanks.

- Ken

-----Original Message-----
From: Chen, Kenneth W
Sent: Thursday, November 14, 2002 7:53 AM
To: Matthew Wilcox; Christian Cotte-Barrot
Cc: [email protected]
Subject: RE: [Linux-ia64] Re: memcpy failure

Quoted 10 lines
Quoted 7 lines · Christian Cotte-Barrot

But memcpy from memcpy.S is returning a pointer to dest area. That would lead to quasi non-portable code when the return from memcopy is correctly checked depending on which memcopy function is addressed. But BTW, is it meaningful to take into account a return code that is always the same and which value is known in advance ? Does memcpy suppose to failed in some cases ?

no, memcpy cannot fail (you get a SIGSEGV in userspace or an MCA in kernel space). checking the return value is meaningless.

That's what I feel as well that it is kind of silly to return something that the caller already has. BUt then, I'm not here to judge the specification ;-)

Anyhow, the fix is fairly easy and won't affect the code size as well as the copy throughput, I should have a patch ready shortly to make everyone happy!

- Ken

_______________________________________________
Linux-IA64 mailing list
[email protected]
http://lists.linuxia64.org/lists/listinfo/linux-ia64

arch/ia64/lib/memcpy_mck.S renamed from arch/ia64/lib/memcpy_mck.S.orig +7 -3
@@ -6,7 +6,10 @@
  *	in1:	source address
  *	in2:	number of bytes to copy
  * Output:
- * 	0 if success, or number of byte NOT copied if error occurred.
+ *	for bcopy:     return nothing
+ *	for memcpy:    retrun dest
+ * 	for copy_user: return 0 if success,
+ *		       or number of byte NOT copied if error occurred.
  *
  * Copyright (C) 2002 Intel Corp.
  * Copyright (C) 2002 Ken Chen <[email protected]>
@@ -86,6 +89,7 @@
 	and	r28=0x7,in0
 	and	r29=0x7,in1
 	mov	f6=f0
+	mov	retval=in0
 	br.cond.sptk .common_code
 	;;
 END(memcpy)
@@ -97,7 +101,7 @@
 	mov	f6=f1
 	mov	saved_in0=in0	// save dest pointer
 	mov	saved_in1=in1	// save src pointer
-	mov	saved_in2=in2	// save len
+	mov	retval=r0	// initialize return value
 	;;
 .common_code:
 	cmp.gt	p15,p0=8,in2	// check for small size
@@ -105,7 +109,7 @@
 	cmp.ne	p14,p0=0,r29	// check src alignment
 	add	src0=0,in1
 	sub	r30=8,r28	// for .align_dest
-	mov	retval=r0	// initialize return value
+	mov	saved_in2=in2	// save len
 	;;
 	add	dst0=0,in0
 	add	dst1=1,in0	// dest odd index
#10 lore raw
In reply to Christian Cotte-Barrot
Quoted 9 lines · Kenneth W
Quoted 8 lines
Quoted 8 lines · Christian Cotte-Barrot

But memcpy from memcpy.S is returning a pointer to dest area. That would lead to quasi non-portable code when the return from memcopy is correctly checked depending on which memcopy function is addressed. But BTW, is it meaningful to take into account a return code that is always the same and which value is known in advance ? Does memcpy suppose to failed in some cases ?

Quoted 7 lines
Quoted 2 lines

no, memcpy cannot fail (you get a SIGSEGV in userspace or an MCA in kernel space). checking the return value is meaningless.

That's what I feel as well that it is kind of silly to return something that the caller already has. BUt then, I'm not here to judge the specification ;-)

Anyhow, the fix is fairly easy and won't affect the code size as well as the copy throughput, I should have a patch ready shortly to make everyone happy!

That's too much noise for a thing with slight importance. It's not a matter of making everyone happy but to provide reliable code. For e.g. if a device driver checks a return as it must because the the function is suppose to provide one, the return code in question must be consistent.
On bad return from memcpy the concerned device driver loggs warning in /var/log/messages and the system administrator may have some doubt about the good working of the device.

Thanks for the patch Ken.

#11 lore raw
In reply to Christian Cotte-Barrot
Quoted 3 lines · Christian Cotte-Barrot

On bad return from memcpy the concerned device driver loggs warning in /var/log/messages and the system administrator may have some doubt about the good working of the device.

_what_ bad return from memcpy?! memcpy returns the pointer that was passed to it. What are you going to check for?

Signature · 1 line
Revolutions do not require corporate support.
#12 lore raw
In reply to Christian Cotte-Barrot
Quoted 9 lines · Matthew Wilcox
Quoted 3 lines · Christian Cotte-Barrot

On bad return from memcpy the concerned device driver loggs warning in /var/log/messages and the system administrator may have some doubt about the good working of the device.

_what_ bad return from memcpy?! memcpy returns the pointer that was passed to it. What are you going to check for?

Simply, bad return is whatever is not equal to the dest pointer:
if ((memcpy(rptr, ch->rxptr + tail, dataToRead)) != rptr)

    ...
#13 lore raw
In reply to Christian Cotte-Barrot
Quoted 8 lines · Christian Cotte-Barrot
Quoted 3 lines · Matthew Wilcox

_what_ bad return from memcpy?! memcpy returns the pointer that was passed to it. What are you going to check for?

Simply, bad return is whatever is not equal to the dest pointer:
if ((memcpy(rptr, ch->rxptr + tail, dataToRead)) != rptr)

    ...

No. You don't get it. memcpy returns the pointer that was passed in. Nothing more, nothing less. There is no error return'. There is no what if'. memcpy is defined to succeed. Look:

"
7.21.2.1 The memcpy function

Synopsis
#include <string.h>
void *memcpy(void * restrict s1, const void * restrict s2, size_t n);

Description
The memcpy function copies n characters from the object pointed to by s2 into the object pointed to by s1. If copying takes place between objects that overlap, the behavior is undefined.

Returns
The memcpy function returns the value of s1.
"

Testing the result of memcpy is bad C. Don't ever do it.

Signature · 1 line
Revolutions do not require corporate support.