diff options
| -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 | ||||
| -rw-r--r-- | include/asm-ia64/sn/xpc.h | 22 |
4 files changed, 85 insertions, 68 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 | ||
diff --git a/include/asm-ia64/sn/xpc.h b/include/asm-ia64/sn/xpc.h index df7f5f4f3cde..aa3b8ace9030 100644 --- a/include/asm-ia64/sn/xpc.h +++ b/include/asm-ia64/sn/xpc.h | |||
| @@ -1227,28 +1227,6 @@ xpc_map_bte_errors(bte_result_t error) | |||
| 1227 | 1227 | ||
| 1228 | 1228 | ||
| 1229 | 1229 | ||
| 1230 | static inline void * | ||
| 1231 | xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base) | ||
| 1232 | { | ||
| 1233 | /* see if kmalloc will give us cachline aligned memory by default */ | ||
| 1234 | *base = kmalloc(size, flags); | ||
| 1235 | if (*base == NULL) { | ||
| 1236 | return NULL; | ||
| 1237 | } | ||
| 1238 | if ((u64) *base == L1_CACHE_ALIGN((u64) *base)) { | ||
| 1239 | return *base; | ||
| 1240 | } | ||
| 1241 | kfree(*base); | ||
| 1242 | |||
| 1243 | /* nope, we'll have to do it ourselves */ | ||
| 1244 | *base = kmalloc(size + L1_CACHE_BYTES, flags); | ||
| 1245 | if (*base == NULL) { | ||
| 1246 | return NULL; | ||
| 1247 | } | ||
| 1248 | return (void *) L1_CACHE_ALIGN((u64) *base); | ||
| 1249 | } | ||
| 1250 | |||
| 1251 | |||
| 1252 | /* | 1230 | /* |
| 1253 | * Check to see if there is any channel activity to/from the specified | 1231 | * Check to see if there is any channel activity to/from the specified |
| 1254 | * partition. | 1232 | * partition. |
