From: alekskartashov@parallels.com (Alexander Kartashov)
To: linux-arm-kernel@lists.infradead.org
Subject: IPC SHM alignment on ARMv7
Date: Thu, 31 Jan 2013 19:35:02 +0400 [thread overview]
Message-ID: <510A8F26.6000609@parallels.com> (raw)
In-Reply-To: <20130131134747.GY23505@n2100.arm.linux.org.uk>
On 01/31/2013 05:47 PM, Russell King - ARM Linux wrote:
> Err, no. Try again
OK, let me be more specific. The following code is a simplified
version of the test in the CRIU test suite that checks IPC SHM
checkpoint/restoration work correctly:
#include <stdio.h>
#include <sys/ipc.h>
int main()
{
int loop;
int shmid = shmget(0x94646337, 40960, IPC_CREAT);
if (shmid < 0) {
perror("Failed to get a SHM descriptor");
return 1;
}
void *addr1, *addr2;
addr1 = shmat(shmid, 0, 0);
if (addr1 == (void*)-1) {
perror("Failed to attach the SHM segment");
return 2;
}
printf("Attached to %p\n", addr1);
*((int*)addr1) = 1;
shmdt(addr1);
addr2 = shmat(shmid, addr1, 0);
if (addr2 == (void*)-1) {
perror("Failed to re-attach the SHM");
printf("The SHM segment was formerly attached to %p\n", addr1);
return 3;
}
if (addr2 != addr1) {
printf("The SHM segment address changed: was %p, now %p\n",
addr1, addr2);
return 4;
}
return 0;
}
I'm running this code in the Linux 3.7.5:
root at crtest:~/ipc-fail# cat /proc/version
Linux version 3.7.5 (alex at alex-pc) (gcc version 4.6.3 20120201
(prerelease) (crosstool-NG linaro-1.13.1-2012.02-20120222 - Linaro GCC
2012.02) ) #1 SMP Thu Jan 31 19:01:37 MSK 2013
I'm running the kernel in the QEMU model of the board RM Versatile
Express for Cortex-A9.
I use the config vexpress_defconfig to compile the kernel.
The test usually outputs something like:
root at crtest:~/ipc-fail# ./ipc-fail
Attached to 0x76e22000
Failed to re-attach the SHM: Invalid argument
The SHM segment was formely attached to 0x76e22000
root at crtest:~/ipc-fail# ./ipc-fail
Attached to 0x76df6000
Failed to re-attach the SHM: Invalid argument
The SHM segment was formely attached to 0x76df6000
However it sometimes succeeds:
root@crtest:~/ipc-fail# ./ipc-fail
Attached to 0x76e94000
As you can see the test fails when the address returned by
the function shmat() isn't SHMLBA-aligned.
I think that this is caused by the fact that the kernel function do_shmat()
requires the argument shmaddr to be SHMLBA-aligned:
[ipc/shm.c]
[...]
958 long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong
*raddr,
959 unsigned long shmlba)
960 {
[...]
974
975 err = -EINVAL;
976 if (shmid < 0)
977 goto out;
978 else if ((addr = (ulong)shmaddr)) {
979 if (addr & (shmlba - 1)) {
980 if (shmflg & SHM_RND)
981 addr &= ~(shmlba - 1); /* round down */
982 else
983 #ifndef __ARCH_FORCE_SHMLBA
984 if (addr & ~PAGE_MASK)
985 #endif
986 goto out;
However, it can't guarantee that its returned address is SHMLBA-aligned
because the function arch_get_unmapped_area():
[arch/arm/mm/mmap.c]
[...]
66 unsigned long
67 arch_get_unmapped_area(struct file *filp, unsigned long addr,
68 unsigned long len, unsigned long pgoff, unsigned long flags)
69 {
70 struct mm_struct *mm = current->mm;
71 struct vm_area_struct *vma;
72 unsigned long start_addr;
73 int do_align = 0;
74 int aliasing = cache_is_vipt_aliasing();
75
76 /*
77 * We only need to do colour alignment if either the I or D
78 * caches alias.
79 */
80 if (aliasing)
81 do_align = filp || (flags & MAP_SHARED);
[...]
114 full_search:
115 if (do_align)
116 addr = COLOUR_ALIGN(addr, pgoff);
117 else
118 addr = PAGE_ALIGN(addr);
119
120 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
121 /* At this point: (!vma || addr < vma->vm_end). */
122 if (TASK_SIZE - len < addr) {
123 /*
124 * Start a new search - just in case we missed
125 * some holes.
126 */
127 if (start_addr != TASK_UNMAPPED_BASE) {
128 start_addr = addr = TASK_UNMAPPED_BASE;
129 mm->cached_hole_size = 0;
130 goto full_search;
131 }
132 return -ENOMEM;
133 }
134 if (!vma || addr + len <= vma->vm_start) {
135 /*
136 * Remember the place where we stopped the search:
137 */
138 mm->free_area_cache = addr + len;
139 return addr;
140 }
141 if (addr + mm->cached_hole_size < vma->vm_start)
142 mm->cached_hole_size = vma->vm_start - addr;
143 addr = vma->vm_end;
144 if (do_align)
145 addr = COLOUR_ALIGN(addr, pgoff);
146 }
147 }
aligns the returned address on a SHMLBA-boundary only if I or D caches alias
as the comment reads:
76 /*
77 * We only need to do colour alignment if either the I or D
78 * caches alias.
79 */
that isn't true for ARMv7.
So the question is whether it's possible to align a SHM segement
on a SHMLBA boundary unconditionally.
--
Sincerely yours,
Alexander Kartashov
Intern
Core team
www.parallels.com
Skype: aleksandr.kartashov
Email: alekskartashov at parallels.com
prev parent reply other threads:[~2013-01-31 15:35 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-31 13:32 IPC SHM alignment on ARMv7 Alexander Kartashov
2013-01-31 13:47 ` Russell King - ARM Linux
2013-01-31 14:08 ` Alexander Kartashov
2013-01-31 15:35 ` Alexander Kartashov [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=510A8F26.6000609@parallels.com \
--to=alekskartashov@parallels.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.