diff options
Diffstat (limited to 'arch/ia64')
-rw-r--r-- | arch/ia64/sn/kernel/xpc_channel.c | 102 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/xpc_main.c | 1 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/xpc_partition.c | 28 |
3 files changed, 85 insertions, 46 deletions
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c index cdf6856ce089..d0abddd9ffe6 100644 --- a/arch/ia64/sn/kernel/xpc_channel.c +++ b/arch/ia64/sn/kernel/xpc_channel.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
22 | #include <linux/cache.h> | 22 | #include <linux/cache.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/slab.h> | ||
25 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
26 | #include <linux/completion.h> | 25 | #include <linux/completion.h> |
27 | #include <asm/sn/bte.h> | 26 | #include <asm/sn/bte.h> |
@@ -30,6 +29,31 @@ | |||
30 | 29 | ||
31 | 30 | ||
32 | /* | 31 | /* |
32 | * Guarantee that the kzalloc'd memory is cacheline aligned. | ||
33 | */ | ||
34 | static void * | ||
35 | xpc_kzalloc_cacheline_aligned(size_t size, gfp_t flags, void **base) | ||
36 | { | ||
37 | /* see if kzalloc will give us cachline aligned memory by default */ | ||
38 | *base = kzalloc(size, flags); | ||
39 | if (*base == NULL) { | ||
40 | return NULL; | ||
41 | } | ||
42 | if ((u64) *base == L1_CACHE_ALIGN((u64) *base)) { | ||
43 | return *base; | ||
44 | } | ||
45 | kfree(*base); | ||
46 | |||
47 | /* nope, we'll have to do it ourselves */ | ||
48 | *base = kzalloc(size + L1_CACHE_BYTES, flags); | ||
49 | if (*base == NULL) { | ||
50 | return NULL; | ||
51 | } | ||
52 | return (void *) L1_CACHE_ALIGN((u64) *base); | ||
53 | } | ||
54 | |||
55 | |||
56 | /* | ||
33 | * Set up the initial values for the XPartition Communication channels. | 57 | * Set up the initial values for the XPartition Communication channels. |
34 | */ | 58 | */ |
35 | static void | 59 | static void |
@@ -93,20 +117,19 @@ xpc_setup_infrastructure(struct xpc_partition *part) | |||
93 | * Allocate all of the channel structures as a contiguous chunk of | 117 | * Allocate all of the channel structures as a contiguous chunk of |
94 | * memory. | 118 | * memory. |
95 | */ | 119 | */ |
96 | part->channels = kmalloc(sizeof(struct xpc_channel) * XPC_NCHANNELS, | 120 | part->channels = kzalloc(sizeof(struct xpc_channel) * XPC_NCHANNELS, |
97 | GFP_KERNEL); | 121 | GFP_KERNEL); |
98 | if (part->channels == NULL) { | 122 | if (part->channels == NULL) { |
99 | dev_err(xpc_chan, "can't get memory for channels\n"); | 123 | dev_err(xpc_chan, "can't get memory for channels\n"); |
100 | return xpcNoMemory; | 124 | return xpcNoMemory; |
101 | } | 125 | } |
102 | memset(part->channels, 0, sizeof(struct xpc_channel) * XPC_NCHANNELS); | ||
103 | 126 | ||
104 | part->nchannels = XPC_NCHANNELS; | 127 | part->nchannels = XPC_NCHANNELS; |
105 | 128 | ||
106 | 129 | ||
107 | /* allocate all the required GET/PUT values */ | 130 | /* allocate all the required GET/PUT values */ |
108 | 131 | ||
109 | part->local_GPs = xpc_kmalloc_cacheline_aligned(XPC_GP_SIZE, | 132 | part->local_GPs = xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE, |
110 | GFP_KERNEL, &part->local_GPs_base); | 133 | GFP_KERNEL, &part->local_GPs_base); |
111 | if (part->local_GPs == NULL) { | 134 | if (part->local_GPs == NULL) { |
112 | kfree(part->channels); | 135 | kfree(part->channels); |
@@ -115,55 +138,51 @@ xpc_setup_infrastructure(struct xpc_partition *part) | |||
115 | "values\n"); | 138 | "values\n"); |
116 | return xpcNoMemory; | 139 | return xpcNoMemory; |
117 | } | 140 | } |
118 | memset(part->local_GPs, 0, XPC_GP_SIZE); | ||
119 | 141 | ||
120 | part->remote_GPs = xpc_kmalloc_cacheline_aligned(XPC_GP_SIZE, | 142 | part->remote_GPs = xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE, |
121 | GFP_KERNEL, &part->remote_GPs_base); | 143 | GFP_KERNEL, &part->remote_GPs_base); |
122 | if (part->remote_GPs == NULL) { | 144 | if (part->remote_GPs == NULL) { |
123 | kfree(part->channels); | ||
124 | part->channels = NULL; | ||
125 | kfree(part->local_GPs_base); | ||
126 | part->local_GPs = NULL; | ||
127 | dev_err(xpc_chan, "can't get memory for remote get/put " | 145 | dev_err(xpc_chan, "can't get memory for remote get/put " |
128 | "values\n"); | 146 | "values\n"); |
147 | kfree(part->local_GPs_base); | ||
148 | part->local_GPs = NULL; | ||
149 | kfree(part->channels); | ||
150 | part->channels = NULL; | ||
129 | return xpcNoMemory; | 151 | return xpcNoMemory; |
130 | } | 152 | } |
131 | memset(part->remote_GPs, 0, XPC_GP_SIZE); | ||
132 | 153 | ||
133 | 154 | ||
134 | /* allocate all the required open and close args */ | 155 | /* allocate all the required open and close args */ |
135 | 156 | ||
136 | part->local_openclose_args = xpc_kmalloc_cacheline_aligned( | 157 | part->local_openclose_args = xpc_kzalloc_cacheline_aligned( |
137 | XPC_OPENCLOSE_ARGS_SIZE, GFP_KERNEL, | 158 | XPC_OPENCLOSE_ARGS_SIZE, GFP_KERNEL, |
138 | &part->local_openclose_args_base); | 159 | &part->local_openclose_args_base); |
139 | if (part->local_openclose_args == NULL) { | 160 | if (part->local_openclose_args == NULL) { |
140 | kfree(part->channels); | 161 | dev_err(xpc_chan, "can't get memory for local connect args\n"); |
141 | part->channels = NULL; | ||
142 | kfree(part->local_GPs_base); | ||
143 | part->local_GPs = NULL; | ||
144 | kfree(part->remote_GPs_base); | 162 | kfree(part->remote_GPs_base); |
145 | part->remote_GPs = NULL; | 163 | part->remote_GPs = NULL; |
146 | dev_err(xpc_chan, "can't get memory for local connect args\n"); | 164 | kfree(part->local_GPs_base); |
165 | part->local_GPs = NULL; | ||
166 | kfree(part->channels); | ||
167 | part->channels = NULL; | ||
147 | return xpcNoMemory; | 168 | return xpcNoMemory; |
148 | } | 169 | } |
149 | memset(part->local_openclose_args, 0, XPC_OPENCLOSE_ARGS_SIZE); | ||
150 | 170 | ||
151 | part->remote_openclose_args = xpc_kmalloc_cacheline_aligned( | 171 | part->remote_openclose_args = xpc_kzalloc_cacheline_aligned( |
152 | XPC_OPENCLOSE_ARGS_SIZE, GFP_KERNEL, | 172 | XPC_OPENCLOSE_ARGS_SIZE, GFP_KERNEL, |
153 | &part->remote_openclose_args_base); | 173 | &part->remote_openclose_args_base); |
154 | if (part->remote_openclose_args == NULL) { | 174 | if (part->remote_openclose_args == NULL) { |
155 | kfree(part->channels); | 175 | dev_err(xpc_chan, "can't get memory for remote connect args\n"); |
156 | part->channels = NULL; | ||
157 | kfree(part->local_GPs_base); | ||
158 | part->local_GPs = NULL; | ||
159 | kfree(part->remote_GPs_base); | ||
160 | part->remote_GPs = NULL; | ||
161 | kfree(part->local_openclose_args_base); | 176 | kfree(part->local_openclose_args_base); |
162 | part->local_openclose_args = NULL; | 177 | part->local_openclose_args = NULL; |
163 | dev_err(xpc_chan, "can't get memory for remote connect args\n"); | 178 | kfree(part->remote_GPs_base); |
179 | part->remote_GPs = NULL; | ||
180 | kfree(part->local_GPs_base); | ||
181 | part->local_GPs = NULL; | ||
182 | kfree(part->channels); | ||
183 | part->channels = NULL; | ||
164 | return xpcNoMemory; | 184 | return xpcNoMemory; |
165 | } | 185 | } |
166 | memset(part->remote_openclose_args, 0, XPC_OPENCLOSE_ARGS_SIZE); | ||
167 | 186 | ||
168 | 187 | ||
169 | xpc_initialize_channels(part, partid); | 188 | xpc_initialize_channels(part, partid); |
@@ -186,18 +205,18 @@ xpc_setup_infrastructure(struct xpc_partition *part) | |||
186 | ret = request_irq(SGI_XPC_NOTIFY, xpc_notify_IRQ_handler, SA_SHIRQ, | 205 | ret = request_irq(SGI_XPC_NOTIFY, xpc_notify_IRQ_handler, SA_SHIRQ, |
187 | part->IPI_owner, (void *) (u64) partid); | 206 | part->IPI_owner, (void *) (u64) partid); |
188 | if (ret != 0) { | 207 | if (ret != 0) { |
189 | kfree(part->channels); | ||
190 | part->channels = NULL; | ||
191 | kfree(part->local_GPs_base); | ||
192 | part->local_GPs = NULL; | ||
193 | kfree(part->remote_GPs_base); | ||
194 | part->remote_GPs = NULL; | ||
195 | kfree(part->local_openclose_args_base); | ||
196 | part->local_openclose_args = NULL; | ||
197 | kfree(part->remote_openclose_args_base); | ||
198 | part->remote_openclose_args = NULL; | ||
199 | dev_err(xpc_chan, "can't register NOTIFY IRQ handler, " | 208 | dev_err(xpc_chan, "can't register NOTIFY IRQ handler, " |
200 | "errno=%d\n", -ret); | 209 | "errno=%d\n", -ret); |
210 | kfree(part->remote_openclose_args_base); | ||
211 | part->remote_openclose_args = NULL; | ||
212 | kfree(part->local_openclose_args_base); | ||
213 | part->local_openclose_args = NULL; | ||
214 | kfree(part->remote_GPs_base); | ||
215 | part->remote_GPs = NULL; | ||
216 | kfree(part->local_GPs_base); | ||
217 | part->local_GPs = NULL; | ||
218 | kfree(part->channels); | ||
219 | part->channels = NULL; | ||
201 | return xpcLackOfResources; | 220 | return xpcLackOfResources; |
202 | } | 221 | } |
203 | 222 | ||
@@ -446,22 +465,20 @@ xpc_allocate_local_msgqueue(struct xpc_channel *ch) | |||
446 | for (nentries = ch->local_nentries; nentries > 0; nentries--) { | 465 | for (nentries = ch->local_nentries; nentries > 0; nentries--) { |
447 | 466 | ||
448 | nbytes = nentries * ch->msg_size; | 467 | nbytes = nentries * ch->msg_size; |
449 | ch->local_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes, | 468 | ch->local_msgqueue = xpc_kzalloc_cacheline_aligned(nbytes, |
450 | GFP_KERNEL, | 469 | GFP_KERNEL, |
451 | &ch->local_msgqueue_base); | 470 | &ch->local_msgqueue_base); |
452 | if (ch->local_msgqueue == NULL) { | 471 | if (ch->local_msgqueue == NULL) { |
453 | continue; | 472 | continue; |
454 | } | 473 | } |
455 | memset(ch->local_msgqueue, 0, nbytes); | ||
456 | 474 | ||
457 | nbytes = nentries * sizeof(struct xpc_notify); | 475 | nbytes = nentries * sizeof(struct xpc_notify); |
458 | ch->notify_queue = kmalloc(nbytes, GFP_KERNEL); | 476 | ch->notify_queue = kzalloc(nbytes, GFP_KERNEL); |
459 | if (ch->notify_queue == NULL) { | 477 | if (ch->notify_queue == NULL) { |
460 | kfree(ch->local_msgqueue_base); | 478 | kfree(ch->local_msgqueue_base); |
461 | ch->local_msgqueue = NULL; | 479 | ch->local_msgqueue = NULL; |
462 | continue; | 480 | continue; |
463 | } | 481 | } |
464 | memset(ch->notify_queue, 0, nbytes); | ||
465 | 482 | ||
466 | spin_lock_irqsave(&ch->lock, irq_flags); | 483 | spin_lock_irqsave(&ch->lock, irq_flags); |
467 | if (nentries < ch->local_nentries) { | 484 | if (nentries < ch->local_nentries) { |
@@ -501,13 +518,12 @@ xpc_allocate_remote_msgqueue(struct xpc_channel *ch) | |||
501 | for (nentries = ch->remote_nentries; nentries > 0; nentries--) { | 518 | for (nentries = ch->remote_nentries; nentries > 0; nentries--) { |
502 | 519 | ||
503 | nbytes = nentries * ch->msg_size; | 520 | nbytes = nentries * ch->msg_size; |
504 | ch->remote_msgqueue = xpc_kmalloc_cacheline_aligned(nbytes, | 521 | ch->remote_msgqueue = xpc_kzalloc_cacheline_aligned(nbytes, |
505 | GFP_KERNEL, | 522 | GFP_KERNEL, |
506 | &ch->remote_msgqueue_base); | 523 | &ch->remote_msgqueue_base); |
507 | if (ch->remote_msgqueue == NULL) { | 524 | if (ch->remote_msgqueue == NULL) { |
508 | continue; | 525 | continue; |
509 | } | 526 | } |
510 | memset(ch->remote_msgqueue, 0, nbytes); | ||
511 | 527 | ||
512 | spin_lock_irqsave(&ch->lock, irq_flags); | 528 | spin_lock_irqsave(&ch->lock, irq_flags); |
513 | if (nentries < ch->remote_nentries) { | 529 | if (nentries < ch->remote_nentries) { |
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c index 8cbf16432570..99b123a6421a 100644 --- a/arch/ia64/sn/kernel/xpc_main.c +++ b/arch/ia64/sn/kernel/xpc_main.c | |||
@@ -52,7 +52,6 @@ | |||
52 | #include <linux/syscalls.h> | 52 | #include <linux/syscalls.h> |
53 | #include <linux/cache.h> | 53 | #include <linux/cache.h> |
54 | #include <linux/interrupt.h> | 54 | #include <linux/interrupt.h> |
55 | #include <linux/slab.h> | ||
56 | #include <linux/delay.h> | 55 | #include <linux/delay.h> |
57 | #include <linux/reboot.h> | 56 | #include <linux/reboot.h> |
58 | #include <linux/completion.h> | 57 | #include <linux/completion.h> |
diff --git a/arch/ia64/sn/kernel/xpc_partition.c b/arch/ia64/sn/kernel/xpc_partition.c index 88a730e6cfdb..94211429fd0c 100644 --- a/arch/ia64/sn/kernel/xpc_partition.c +++ b/arch/ia64/sn/kernel/xpc_partition.c | |||
@@ -81,6 +81,31 @@ char ____cacheline_aligned xpc_remote_copy_buffer[XPC_RP_HEADER_SIZE + | |||
81 | 81 | ||
82 | 82 | ||
83 | /* | 83 | /* |
84 | * Guarantee that the kmalloc'd memory is cacheline aligned. | ||
85 | */ | ||
86 | static void * | ||
87 | xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base) | ||
88 | { | ||
89 | /* see if kmalloc will give us cachline aligned memory by default */ | ||
90 | *base = kmalloc(size, flags); | ||
91 | if (*base == NULL) { | ||
92 | return NULL; | ||
93 | } | ||
94 | if ((u64) *base == L1_CACHE_ALIGN((u64) *base)) { | ||
95 | return *base; | ||
96 | } | ||
97 | kfree(*base); | ||
98 | |||
99 | /* nope, we'll have to do it ourselves */ | ||
100 | *base = kmalloc(size + L1_CACHE_BYTES, flags); | ||
101 | if (*base == NULL) { | ||
102 | return NULL; | ||
103 | } | ||
104 | return (void *) L1_CACHE_ALIGN((u64) *base); | ||
105 | } | ||
106 | |||
107 | |||
108 | /* | ||
84 | * Given a nasid, get the physical address of the partition's reserved page | 109 | * Given a nasid, get the physical address of the partition's reserved page |
85 | * for that nasid. This function returns 0 on any error. | 110 | * for that nasid. This function returns 0 on any error. |
86 | */ | 111 | */ |
@@ -1038,13 +1063,12 @@ xpc_discovery(void) | |||
1038 | remote_vars = (struct xpc_vars *) remote_rp; | 1063 | remote_vars = (struct xpc_vars *) remote_rp; |
1039 | 1064 | ||
1040 | 1065 | ||
1041 | discovered_nasids = kmalloc(sizeof(u64) * xp_nasid_mask_words, | 1066 | discovered_nasids = kzalloc(sizeof(u64) * xp_nasid_mask_words, |
1042 | GFP_KERNEL); | 1067 | GFP_KERNEL); |
1043 | if (discovered_nasids == NULL) { | 1068 | if (discovered_nasids == NULL) { |
1044 | kfree(remote_rp_base); | 1069 | kfree(remote_rp_base); |
1045 | return; | 1070 | return; |
1046 | } | 1071 | } |
1047 | memset(discovered_nasids, 0, sizeof(u64) * xp_nasid_mask_words); | ||
1048 | 1072 | ||
1049 | rp = (struct xpc_rsvd_page *) xpc_rsvd_page; | 1073 | rp = (struct xpc_rsvd_page *) xpc_rsvd_page; |
1050 | 1074 | ||