diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-11-13 12:52:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-11-13 12:52:04 -0500 |
commit | 0f66c08e9611b9a63f2f2fd5af0d12e486c4a02e (patch) | |
tree | 0e36f48f32c97c4ef9ed5fcd6158226345f43d2e /drivers/infiniband | |
parent | 4dd7406e9c7e7a5422425ef699780463490b8745 (diff) | |
parent | 39798695b4bcc7b145f8910ca56195808d3a7637 (diff) |
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband:
IB/mad: Fix race between cancel and receive completion
RDMA/amso1100: Fix && typo
RDMA/amso1100: Fix unitialized pseudo_netdev accessed in c2_register_device
IB/ehca: Activate scaling code by default
IB/ehca: Use named constant for max mtu
IB/ehca: Assure 4K alignment for firmware control blocks
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/mad.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/amso1100/c2.c | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/amso1100/c2_provider.c | 39 | ||||
-rw-r--r-- | drivers/infiniband/hw/amso1100/c2_rnic.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/Kconfig | 1 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_av.c | 5 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_hca.c | 17 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_irq.c | 17 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_iverbs.h | 8 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_main.c | 56 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_mrmw.c | 8 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_qp.c | 10 | ||||
-rw-r--r-- | drivers/infiniband/hw/ehca/hipz_hw.h | 2 |
13 files changed, 111 insertions, 61 deletions
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 493f4c65c7a2..a72bcea46ff6 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -1750,7 +1750,7 @@ ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, | |||
1750 | */ | 1750 | */ |
1751 | (is_direct(wc->recv_buf.mad->mad_hdr.mgmt_class) || | 1751 | (is_direct(wc->recv_buf.mad->mad_hdr.mgmt_class) || |
1752 | rcv_has_same_gid(mad_agent_priv, wr, wc))) | 1752 | rcv_has_same_gid(mad_agent_priv, wr, wc))) |
1753 | return wr; | 1753 | return (wr->status == IB_WC_SUCCESS) ? wr : NULL; |
1754 | } | 1754 | } |
1755 | 1755 | ||
1756 | /* | 1756 | /* |
diff --git a/drivers/infiniband/hw/amso1100/c2.c b/drivers/infiniband/hw/amso1100/c2.c index 9e7bd94b958a..27fe242ed435 100644 --- a/drivers/infiniband/hw/amso1100/c2.c +++ b/drivers/infiniband/hw/amso1100/c2.c | |||
@@ -1155,7 +1155,8 @@ static int __devinit c2_probe(struct pci_dev *pcidev, | |||
1155 | goto bail10; | 1155 | goto bail10; |
1156 | } | 1156 | } |
1157 | 1157 | ||
1158 | c2_register_device(c2dev); | 1158 | if (c2_register_device(c2dev)) |
1159 | goto bail10; | ||
1159 | 1160 | ||
1160 | return 0; | 1161 | return 0; |
1161 | 1162 | ||
diff --git a/drivers/infiniband/hw/amso1100/c2_provider.c b/drivers/infiniband/hw/amso1100/c2_provider.c index da98d9f71429..fef972752912 100644 --- a/drivers/infiniband/hw/amso1100/c2_provider.c +++ b/drivers/infiniband/hw/amso1100/c2_provider.c | |||
@@ -757,20 +757,17 @@ static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev) | |||
757 | 757 | ||
758 | int c2_register_device(struct c2_dev *dev) | 758 | int c2_register_device(struct c2_dev *dev) |
759 | { | 759 | { |
760 | int ret; | 760 | int ret = -ENOMEM; |
761 | int i; | 761 | int i; |
762 | 762 | ||
763 | /* Register pseudo network device */ | 763 | /* Register pseudo network device */ |
764 | dev->pseudo_netdev = c2_pseudo_netdev_init(dev); | 764 | dev->pseudo_netdev = c2_pseudo_netdev_init(dev); |
765 | if (dev->pseudo_netdev) { | 765 | if (!dev->pseudo_netdev) |
766 | ret = register_netdev(dev->pseudo_netdev); | 766 | goto out3; |
767 | if (ret) { | 767 | |
768 | printk(KERN_ERR PFX | 768 | ret = register_netdev(dev->pseudo_netdev); |
769 | "Unable to register netdev, ret = %d\n", ret); | 769 | if (ret) |
770 | free_netdev(dev->pseudo_netdev); | 770 | goto out2; |
771 | return ret; | ||
772 | } | ||
773 | } | ||
774 | 771 | ||
775 | pr_debug("%s:%u\n", __FUNCTION__, __LINE__); | 772 | pr_debug("%s:%u\n", __FUNCTION__, __LINE__); |
776 | strlcpy(dev->ibdev.name, "amso%d", IB_DEVICE_NAME_MAX); | 773 | strlcpy(dev->ibdev.name, "amso%d", IB_DEVICE_NAME_MAX); |
@@ -848,21 +845,25 @@ int c2_register_device(struct c2_dev *dev) | |||
848 | 845 | ||
849 | ret = ib_register_device(&dev->ibdev); | 846 | ret = ib_register_device(&dev->ibdev); |
850 | if (ret) | 847 | if (ret) |
851 | return ret; | 848 | goto out1; |
852 | 849 | ||
853 | for (i = 0; i < ARRAY_SIZE(c2_class_attributes); ++i) { | 850 | for (i = 0; i < ARRAY_SIZE(c2_class_attributes); ++i) { |
854 | ret = class_device_create_file(&dev->ibdev.class_dev, | 851 | ret = class_device_create_file(&dev->ibdev.class_dev, |
855 | c2_class_attributes[i]); | 852 | c2_class_attributes[i]); |
856 | if (ret) { | 853 | if (ret) |
857 | unregister_netdev(dev->pseudo_netdev); | 854 | goto out0; |
858 | free_netdev(dev->pseudo_netdev); | ||
859 | ib_unregister_device(&dev->ibdev); | ||
860 | return ret; | ||
861 | } | ||
862 | } | 855 | } |
856 | goto out3; | ||
863 | 857 | ||
864 | pr_debug("%s:%u\n", __FUNCTION__, __LINE__); | 858 | out0: |
865 | return 0; | 859 | ib_unregister_device(&dev->ibdev); |
860 | out1: | ||
861 | unregister_netdev(dev->pseudo_netdev); | ||
862 | out2: | ||
863 | free_netdev(dev->pseudo_netdev); | ||
864 | out3: | ||
865 | pr_debug("%s:%u ret=%d\n", __FUNCTION__, __LINE__, ret); | ||
866 | return ret; | ||
866 | } | 867 | } |
867 | 868 | ||
868 | void c2_unregister_device(struct c2_dev *dev) | 869 | void c2_unregister_device(struct c2_dev *dev) |
diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c index 21d9612a56cc..623dc95f91df 100644 --- a/drivers/infiniband/hw/amso1100/c2_rnic.c +++ b/drivers/infiniband/hw/amso1100/c2_rnic.c | |||
@@ -157,8 +157,8 @@ static int c2_rnic_query(struct c2_dev *c2dev, struct ib_device_attr *props) | |||
157 | 157 | ||
158 | props->fw_ver = | 158 | props->fw_ver = |
159 | ((u64)be32_to_cpu(reply->fw_ver_major) << 32) | | 159 | ((u64)be32_to_cpu(reply->fw_ver_major) << 32) | |
160 | ((be32_to_cpu(reply->fw_ver_minor) && 0xFFFF) << 16) | | 160 | ((be32_to_cpu(reply->fw_ver_minor) & 0xFFFF) << 16) | |
161 | (be32_to_cpu(reply->fw_ver_patch) && 0xFFFF); | 161 | (be32_to_cpu(reply->fw_ver_patch) & 0xFFFF); |
162 | memcpy(&props->sys_image_guid, c2dev->netdev->dev_addr, 6); | 162 | memcpy(&props->sys_image_guid, c2dev->netdev->dev_addr, 6); |
163 | props->max_mr_size = 0xFFFFFFFF; | 163 | props->max_mr_size = 0xFFFFFFFF; |
164 | props->page_size_cap = ~(C2_MIN_PAGESIZE-1); | 164 | props->page_size_cap = ~(C2_MIN_PAGESIZE-1); |
diff --git a/drivers/infiniband/hw/ehca/Kconfig b/drivers/infiniband/hw/ehca/Kconfig index 922389b64394..727b10d89686 100644 --- a/drivers/infiniband/hw/ehca/Kconfig +++ b/drivers/infiniband/hw/ehca/Kconfig | |||
@@ -10,6 +10,7 @@ config INFINIBAND_EHCA | |||
10 | config INFINIBAND_EHCA_SCALING | 10 | config INFINIBAND_EHCA_SCALING |
11 | bool "Scaling support (EXPERIMENTAL)" | 11 | bool "Scaling support (EXPERIMENTAL)" |
12 | depends on IBMEBUS && INFINIBAND_EHCA && HOTPLUG_CPU && EXPERIMENTAL | 12 | depends on IBMEBUS && INFINIBAND_EHCA && HOTPLUG_CPU && EXPERIMENTAL |
13 | default y | ||
13 | ---help--- | 14 | ---help--- |
14 | eHCA scaling support schedules the CQ callbacks to different CPUs. | 15 | eHCA scaling support schedules the CQ callbacks to different CPUs. |
15 | 16 | ||
diff --git a/drivers/infiniband/hw/ehca/ehca_av.c b/drivers/infiniband/hw/ehca/ehca_av.c index 3bac197f9014..214e2fdddeef 100644 --- a/drivers/infiniband/hw/ehca/ehca_av.c +++ b/drivers/infiniband/hw/ehca/ehca_av.c | |||
@@ -118,8 +118,7 @@ struct ib_ah *ehca_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) | |||
118 | } | 118 | } |
119 | memcpy(&av->av.grh.word_1, &gid, sizeof(gid)); | 119 | memcpy(&av->av.grh.word_1, &gid, sizeof(gid)); |
120 | } | 120 | } |
121 | /* for the time being we use a hard coded PMTU of 2048 Bytes */ | 121 | av->av.pmtu = EHCA_MAX_MTU; |
122 | av->av.pmtu = 4; | ||
123 | 122 | ||
124 | /* dgid comes in grh.word_3 */ | 123 | /* dgid comes in grh.word_3 */ |
125 | memcpy(&av->av.grh.word_3, &ah_attr->grh.dgid, | 124 | memcpy(&av->av.grh.word_3, &ah_attr->grh.dgid, |
@@ -193,7 +192,7 @@ int ehca_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr) | |||
193 | memcpy(&new_ehca_av.grh.word_1, &gid, sizeof(gid)); | 192 | memcpy(&new_ehca_av.grh.word_1, &gid, sizeof(gid)); |
194 | } | 193 | } |
195 | 194 | ||
196 | new_ehca_av.pmtu = 4; /* see also comment in create_ah() */ | 195 | new_ehca_av.pmtu = EHCA_MAX_MTU; |
197 | 196 | ||
198 | memcpy(&new_ehca_av.grh.word_3, &ah_attr->grh.dgid, | 197 | memcpy(&new_ehca_av.grh.word_3, &ah_attr->grh.dgid, |
199 | sizeof(ah_attr->grh.dgid)); | 198 | sizeof(ah_attr->grh.dgid)); |
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c index 5eae6ac48425..e1b618c5f685 100644 --- a/drivers/infiniband/hw/ehca/ehca_hca.c +++ b/drivers/infiniband/hw/ehca/ehca_hca.c | |||
@@ -40,6 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "ehca_tools.h" | 42 | #include "ehca_tools.h" |
43 | #include "ehca_iverbs.h" | ||
43 | #include "hcp_if.h" | 44 | #include "hcp_if.h" |
44 | 45 | ||
45 | int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) | 46 | int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) |
@@ -49,7 +50,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) | |||
49 | ib_device); | 50 | ib_device); |
50 | struct hipz_query_hca *rblock; | 51 | struct hipz_query_hca *rblock; |
51 | 52 | ||
52 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 53 | rblock = ehca_alloc_fw_ctrlblock(); |
53 | if (!rblock) { | 54 | if (!rblock) { |
54 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); | 55 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); |
55 | return -ENOMEM; | 56 | return -ENOMEM; |
@@ -96,7 +97,7 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props) | |||
96 | = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX); | 97 | = min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX); |
97 | 98 | ||
98 | query_device1: | 99 | query_device1: |
99 | kfree(rblock); | 100 | ehca_free_fw_ctrlblock(rblock); |
100 | 101 | ||
101 | return ret; | 102 | return ret; |
102 | } | 103 | } |
@@ -109,7 +110,7 @@ int ehca_query_port(struct ib_device *ibdev, | |||
109 | ib_device); | 110 | ib_device); |
110 | struct hipz_query_port *rblock; | 111 | struct hipz_query_port *rblock; |
111 | 112 | ||
112 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 113 | rblock = ehca_alloc_fw_ctrlblock(); |
113 | if (!rblock) { | 114 | if (!rblock) { |
114 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); | 115 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); |
115 | return -ENOMEM; | 116 | return -ENOMEM; |
@@ -162,7 +163,7 @@ int ehca_query_port(struct ib_device *ibdev, | |||
162 | props->active_speed = 0x1; | 163 | props->active_speed = 0x1; |
163 | 164 | ||
164 | query_port1: | 165 | query_port1: |
165 | kfree(rblock); | 166 | ehca_free_fw_ctrlblock(rblock); |
166 | 167 | ||
167 | return ret; | 168 | return ret; |
168 | } | 169 | } |
@@ -178,7 +179,7 @@ int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey) | |||
178 | return -EINVAL; | 179 | return -EINVAL; |
179 | } | 180 | } |
180 | 181 | ||
181 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 182 | rblock = ehca_alloc_fw_ctrlblock(); |
182 | if (!rblock) { | 183 | if (!rblock) { |
183 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); | 184 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); |
184 | return -ENOMEM; | 185 | return -ENOMEM; |
@@ -193,7 +194,7 @@ int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey) | |||
193 | memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16)); | 194 | memcpy(pkey, &rblock->pkey_entries + index, sizeof(u16)); |
194 | 195 | ||
195 | query_pkey1: | 196 | query_pkey1: |
196 | kfree(rblock); | 197 | ehca_free_fw_ctrlblock(rblock); |
197 | 198 | ||
198 | return ret; | 199 | return ret; |
199 | } | 200 | } |
@@ -211,7 +212,7 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port, | |||
211 | return -EINVAL; | 212 | return -EINVAL; |
212 | } | 213 | } |
213 | 214 | ||
214 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 215 | rblock = ehca_alloc_fw_ctrlblock(); |
215 | if (!rblock) { | 216 | if (!rblock) { |
216 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); | 217 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); |
217 | return -ENOMEM; | 218 | return -ENOMEM; |
@@ -227,7 +228,7 @@ int ehca_query_gid(struct ib_device *ibdev, u8 port, | |||
227 | memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64)); | 228 | memcpy(&gid->raw[8], &rblock->guid_entries[index], sizeof(u64)); |
228 | 229 | ||
229 | query_gid1: | 230 | query_gid1: |
230 | kfree(rblock); | 231 | ehca_free_fw_ctrlblock(rblock); |
231 | 232 | ||
232 | return ret; | 233 | return ret; |
233 | } | 234 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c index 048cc443d1e7..c3ea746e9045 100644 --- a/drivers/infiniband/hw/ehca/ehca_irq.c +++ b/drivers/infiniband/hw/ehca/ehca_irq.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include "ehca_tools.h" | 45 | #include "ehca_tools.h" |
46 | #include "hcp_if.h" | 46 | #include "hcp_if.h" |
47 | #include "hipz_fns.h" | 47 | #include "hipz_fns.h" |
48 | #include "ipz_pt_fn.h" | ||
48 | 49 | ||
49 | #define EQE_COMPLETION_EVENT EHCA_BMASK_IBM(1,1) | 50 | #define EQE_COMPLETION_EVENT EHCA_BMASK_IBM(1,1) |
50 | #define EQE_CQ_QP_NUMBER EHCA_BMASK_IBM(8,31) | 51 | #define EQE_CQ_QP_NUMBER EHCA_BMASK_IBM(8,31) |
@@ -137,38 +138,36 @@ int ehca_error_data(struct ehca_shca *shca, void *data, | |||
137 | u64 *rblock; | 138 | u64 *rblock; |
138 | unsigned long block_count; | 139 | unsigned long block_count; |
139 | 140 | ||
140 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 141 | rblock = ehca_alloc_fw_ctrlblock(); |
141 | if (!rblock) { | 142 | if (!rblock) { |
142 | ehca_err(&shca->ib_device, "Cannot allocate rblock memory."); | 143 | ehca_err(&shca->ib_device, "Cannot allocate rblock memory."); |
143 | ret = -ENOMEM; | 144 | ret = -ENOMEM; |
144 | goto error_data1; | 145 | goto error_data1; |
145 | } | 146 | } |
146 | 147 | ||
148 | /* rblock must be 4K aligned and should be 4K large */ | ||
147 | ret = hipz_h_error_data(shca->ipz_hca_handle, | 149 | ret = hipz_h_error_data(shca->ipz_hca_handle, |
148 | resource, | 150 | resource, |
149 | rblock, | 151 | rblock, |
150 | &block_count); | 152 | &block_count); |
151 | 153 | ||
152 | if (ret == H_R_STATE) { | 154 | if (ret == H_R_STATE) |
153 | ehca_err(&shca->ib_device, | 155 | ehca_err(&shca->ib_device, |
154 | "No error data is available: %lx.", resource); | 156 | "No error data is available: %lx.", resource); |
155 | } | ||
156 | else if (ret == H_SUCCESS) { | 157 | else if (ret == H_SUCCESS) { |
157 | int length; | 158 | int length; |
158 | 159 | ||
159 | length = EHCA_BMASK_GET(ERROR_DATA_LENGTH, rblock[0]); | 160 | length = EHCA_BMASK_GET(ERROR_DATA_LENGTH, rblock[0]); |
160 | 161 | ||
161 | if (length > PAGE_SIZE) | 162 | if (length > EHCA_PAGESIZE) |
162 | length = PAGE_SIZE; | 163 | length = EHCA_PAGESIZE; |
163 | 164 | ||
164 | print_error_data(shca, data, rblock, length); | 165 | print_error_data(shca, data, rblock, length); |
165 | } | 166 | } else |
166 | else { | ||
167 | ehca_err(&shca->ib_device, | 167 | ehca_err(&shca->ib_device, |
168 | "Error data could not be fetched: %lx", resource); | 168 | "Error data could not be fetched: %lx", resource); |
169 | } | ||
170 | 169 | ||
171 | kfree(rblock); | 170 | ehca_free_fw_ctrlblock(rblock); |
172 | 171 | ||
173 | error_data1: | 172 | error_data1: |
174 | return ret; | 173 | return ret; |
diff --git a/drivers/infiniband/hw/ehca/ehca_iverbs.h b/drivers/infiniband/hw/ehca/ehca_iverbs.h index 319c39d47f3a..3720e3032cce 100644 --- a/drivers/infiniband/hw/ehca/ehca_iverbs.h +++ b/drivers/infiniband/hw/ehca/ehca_iverbs.h | |||
@@ -179,4 +179,12 @@ int ehca_mmap_register(u64 physical,void **mapped, | |||
179 | 179 | ||
180 | int ehca_munmap(unsigned long addr, size_t len); | 180 | int ehca_munmap(unsigned long addr, size_t len); |
181 | 181 | ||
182 | #ifdef CONFIG_PPC_64K_PAGES | ||
183 | void *ehca_alloc_fw_ctrlblock(void); | ||
184 | void ehca_free_fw_ctrlblock(void *ptr); | ||
185 | #else | ||
186 | #define ehca_alloc_fw_ctrlblock() ((void *) get_zeroed_page(GFP_KERNEL)) | ||
187 | #define ehca_free_fw_ctrlblock(ptr) free_page((unsigned long)(ptr)) | ||
188 | #endif | ||
189 | |||
182 | #endif | 190 | #endif |
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index 024d511c4b58..01f5aa9cb56d 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
@@ -40,6 +40,9 @@ | |||
40 | * POSSIBILITY OF SUCH DAMAGE. | 40 | * POSSIBILITY OF SUCH DAMAGE. |
41 | */ | 41 | */ |
42 | 42 | ||
43 | #ifdef CONFIG_PPC_64K_PAGES | ||
44 | #include <linux/slab.h> | ||
45 | #endif | ||
43 | #include "ehca_classes.h" | 46 | #include "ehca_classes.h" |
44 | #include "ehca_iverbs.h" | 47 | #include "ehca_iverbs.h" |
45 | #include "ehca_mrmw.h" | 48 | #include "ehca_mrmw.h" |
@@ -49,7 +52,7 @@ | |||
49 | MODULE_LICENSE("Dual BSD/GPL"); | 52 | MODULE_LICENSE("Dual BSD/GPL"); |
50 | MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); | 53 | MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); |
51 | MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); | 54 | MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); |
52 | MODULE_VERSION("SVNEHCA_0017"); | 55 | MODULE_VERSION("SVNEHCA_0018"); |
53 | 56 | ||
54 | int ehca_open_aqp1 = 0; | 57 | int ehca_open_aqp1 = 0; |
55 | int ehca_debug_level = 0; | 58 | int ehca_debug_level = 0; |
@@ -94,11 +97,31 @@ spinlock_t ehca_cq_idr_lock; | |||
94 | DEFINE_IDR(ehca_qp_idr); | 97 | DEFINE_IDR(ehca_qp_idr); |
95 | DEFINE_IDR(ehca_cq_idr); | 98 | DEFINE_IDR(ehca_cq_idr); |
96 | 99 | ||
100 | |||
97 | static struct list_head shca_list; /* list of all registered ehcas */ | 101 | static struct list_head shca_list; /* list of all registered ehcas */ |
98 | static spinlock_t shca_list_lock; | 102 | static spinlock_t shca_list_lock; |
99 | 103 | ||
100 | static struct timer_list poll_eqs_timer; | 104 | static struct timer_list poll_eqs_timer; |
101 | 105 | ||
106 | #ifdef CONFIG_PPC_64K_PAGES | ||
107 | static struct kmem_cache *ctblk_cache = NULL; | ||
108 | |||
109 | void *ehca_alloc_fw_ctrlblock(void) | ||
110 | { | ||
111 | void *ret = kmem_cache_zalloc(ctblk_cache, SLAB_KERNEL); | ||
112 | if (!ret) | ||
113 | ehca_gen_err("Out of memory for ctblk"); | ||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | void ehca_free_fw_ctrlblock(void *ptr) | ||
118 | { | ||
119 | if (ptr) | ||
120 | kmem_cache_free(ctblk_cache, ptr); | ||
121 | |||
122 | } | ||
123 | #endif | ||
124 | |||
102 | static int ehca_create_slab_caches(void) | 125 | static int ehca_create_slab_caches(void) |
103 | { | 126 | { |
104 | int ret; | 127 | int ret; |
@@ -133,6 +156,17 @@ static int ehca_create_slab_caches(void) | |||
133 | goto create_slab_caches5; | 156 | goto create_slab_caches5; |
134 | } | 157 | } |
135 | 158 | ||
159 | #ifdef CONFIG_PPC_64K_PAGES | ||
160 | ctblk_cache = kmem_cache_create("ehca_cache_ctblk", | ||
161 | EHCA_PAGESIZE, H_CB_ALIGNMENT, | ||
162 | SLAB_HWCACHE_ALIGN, | ||
163 | NULL, NULL); | ||
164 | if (!ctblk_cache) { | ||
165 | ehca_gen_err("Cannot create ctblk SLAB cache."); | ||
166 | ehca_cleanup_mrmw_cache(); | ||
167 | goto create_slab_caches5; | ||
168 | } | ||
169 | #endif | ||
136 | return 0; | 170 | return 0; |
137 | 171 | ||
138 | create_slab_caches5: | 172 | create_slab_caches5: |
@@ -157,6 +191,10 @@ static void ehca_destroy_slab_caches(void) | |||
157 | ehca_cleanup_qp_cache(); | 191 | ehca_cleanup_qp_cache(); |
158 | ehca_cleanup_cq_cache(); | 192 | ehca_cleanup_cq_cache(); |
159 | ehca_cleanup_pd_cache(); | 193 | ehca_cleanup_pd_cache(); |
194 | #ifdef CONFIG_PPC_64K_PAGES | ||
195 | if (ctblk_cache) | ||
196 | kmem_cache_destroy(ctblk_cache); | ||
197 | #endif | ||
160 | } | 198 | } |
161 | 199 | ||
162 | #define EHCA_HCAAVER EHCA_BMASK_IBM(32,39) | 200 | #define EHCA_HCAAVER EHCA_BMASK_IBM(32,39) |
@@ -168,7 +206,7 @@ int ehca_sense_attributes(struct ehca_shca *shca) | |||
168 | u64 h_ret; | 206 | u64 h_ret; |
169 | struct hipz_query_hca *rblock; | 207 | struct hipz_query_hca *rblock; |
170 | 208 | ||
171 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 209 | rblock = ehca_alloc_fw_ctrlblock(); |
172 | if (!rblock) { | 210 | if (!rblock) { |
173 | ehca_gen_err("Cannot allocate rblock memory."); | 211 | ehca_gen_err("Cannot allocate rblock memory."); |
174 | return -ENOMEM; | 212 | return -ENOMEM; |
@@ -211,7 +249,7 @@ int ehca_sense_attributes(struct ehca_shca *shca) | |||
211 | shca->sport[1].rate = IB_RATE_30_GBPS; | 249 | shca->sport[1].rate = IB_RATE_30_GBPS; |
212 | 250 | ||
213 | num_ports1: | 251 | num_ports1: |
214 | kfree(rblock); | 252 | ehca_free_fw_ctrlblock(rblock); |
215 | return ret; | 253 | return ret; |
216 | } | 254 | } |
217 | 255 | ||
@@ -220,7 +258,7 @@ static int init_node_guid(struct ehca_shca *shca) | |||
220 | int ret = 0; | 258 | int ret = 0; |
221 | struct hipz_query_hca *rblock; | 259 | struct hipz_query_hca *rblock; |
222 | 260 | ||
223 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 261 | rblock = ehca_alloc_fw_ctrlblock(); |
224 | if (!rblock) { | 262 | if (!rblock) { |
225 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); | 263 | ehca_err(&shca->ib_device, "Can't allocate rblock memory."); |
226 | return -ENOMEM; | 264 | return -ENOMEM; |
@@ -235,7 +273,7 @@ static int init_node_guid(struct ehca_shca *shca) | |||
235 | memcpy(&shca->ib_device.node_guid, &rblock->node_guid, sizeof(u64)); | 273 | memcpy(&shca->ib_device.node_guid, &rblock->node_guid, sizeof(u64)); |
236 | 274 | ||
237 | init_node_guid1: | 275 | init_node_guid1: |
238 | kfree(rblock); | 276 | ehca_free_fw_ctrlblock(rblock); |
239 | return ret; | 277 | return ret; |
240 | } | 278 | } |
241 | 279 | ||
@@ -431,7 +469,7 @@ static ssize_t ehca_show_##name(struct device *dev, \ | |||
431 | \ | 469 | \ |
432 | shca = dev->driver_data; \ | 470 | shca = dev->driver_data; \ |
433 | \ | 471 | \ |
434 | rblock = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); \ | 472 | rblock = ehca_alloc_fw_ctrlblock(); \ |
435 | if (!rblock) { \ | 473 | if (!rblock) { \ |
436 | dev_err(dev, "Can't allocate rblock memory."); \ | 474 | dev_err(dev, "Can't allocate rblock memory."); \ |
437 | return 0; \ | 475 | return 0; \ |
@@ -439,12 +477,12 @@ static ssize_t ehca_show_##name(struct device *dev, \ | |||
439 | \ | 477 | \ |
440 | if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \ | 478 | if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \ |
441 | dev_err(dev, "Can't query device properties"); \ | 479 | dev_err(dev, "Can't query device properties"); \ |
442 | kfree(rblock); \ | 480 | ehca_free_fw_ctrlblock(rblock); \ |
443 | return 0; \ | 481 | return 0; \ |
444 | } \ | 482 | } \ |
445 | \ | 483 | \ |
446 | data = rblock->name; \ | 484 | data = rblock->name; \ |
447 | kfree(rblock); \ | 485 | ehca_free_fw_ctrlblock(rblock); \ |
448 | \ | 486 | \ |
449 | if ((strcmp(#name, "num_ports") == 0) && (ehca_nr_ports == 1)) \ | 487 | if ((strcmp(#name, "num_ports") == 0) && (ehca_nr_ports == 1)) \ |
450 | return snprintf(buf, 256, "1\n"); \ | 488 | return snprintf(buf, 256, "1\n"); \ |
@@ -752,7 +790,7 @@ int __init ehca_module_init(void) | |||
752 | int ret; | 790 | int ret; |
753 | 791 | ||
754 | printk(KERN_INFO "eHCA Infiniband Device Driver " | 792 | printk(KERN_INFO "eHCA Infiniband Device Driver " |
755 | "(Rel.: SVNEHCA_0017)\n"); | 793 | "(Rel.: SVNEHCA_0018)\n"); |
756 | idr_init(&ehca_qp_idr); | 794 | idr_init(&ehca_qp_idr); |
757 | idr_init(&ehca_cq_idr); | 795 | idr_init(&ehca_cq_idr); |
758 | spin_lock_init(&ehca_qp_idr_lock); | 796 | spin_lock_init(&ehca_qp_idr_lock); |
diff --git a/drivers/infiniband/hw/ehca/ehca_mrmw.c b/drivers/infiniband/hw/ehca/ehca_mrmw.c index 5ca65441e1da..abce676c0ae0 100644 --- a/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/drivers/infiniband/hw/ehca/ehca_mrmw.c | |||
@@ -1013,7 +1013,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, | |||
1013 | u32 i; | 1013 | u32 i; |
1014 | u64 *kpage; | 1014 | u64 *kpage; |
1015 | 1015 | ||
1016 | kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 1016 | kpage = ehca_alloc_fw_ctrlblock(); |
1017 | if (!kpage) { | 1017 | if (!kpage) { |
1018 | ehca_err(&shca->ib_device, "kpage alloc failed"); | 1018 | ehca_err(&shca->ib_device, "kpage alloc failed"); |
1019 | ret = -ENOMEM; | 1019 | ret = -ENOMEM; |
@@ -1092,7 +1092,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, | |||
1092 | 1092 | ||
1093 | 1093 | ||
1094 | ehca_reg_mr_rpages_exit1: | 1094 | ehca_reg_mr_rpages_exit1: |
1095 | kfree(kpage); | 1095 | ehca_free_fw_ctrlblock(kpage); |
1096 | ehca_reg_mr_rpages_exit0: | 1096 | ehca_reg_mr_rpages_exit0: |
1097 | if (ret) | 1097 | if (ret) |
1098 | ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p pginfo=%p " | 1098 | ehca_err(&shca->ib_device, "ret=%x shca=%p e_mr=%p pginfo=%p " |
@@ -1124,7 +1124,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca, | |||
1124 | ehca_mrmw_map_acl(acl, &hipz_acl); | 1124 | ehca_mrmw_map_acl(acl, &hipz_acl); |
1125 | ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); | 1125 | ehca_mrmw_set_pgsize_hipz_acl(&hipz_acl); |
1126 | 1126 | ||
1127 | kpage = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 1127 | kpage = ehca_alloc_fw_ctrlblock(); |
1128 | if (!kpage) { | 1128 | if (!kpage) { |
1129 | ehca_err(&shca->ib_device, "kpage alloc failed"); | 1129 | ehca_err(&shca->ib_device, "kpage alloc failed"); |
1130 | ret = -ENOMEM; | 1130 | ret = -ENOMEM; |
@@ -1181,7 +1181,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca, | |||
1181 | } | 1181 | } |
1182 | 1182 | ||
1183 | ehca_rereg_mr_rereg1_exit1: | 1183 | ehca_rereg_mr_rereg1_exit1: |
1184 | kfree(kpage); | 1184 | ehca_free_fw_ctrlblock(kpage); |
1185 | ehca_rereg_mr_rereg1_exit0: | 1185 | ehca_rereg_mr_rereg1_exit0: |
1186 | if ( ret && (ret != -EAGAIN) ) | 1186 | if ( ret && (ret != -EAGAIN) ) |
1187 | ehca_err(&shca->ib_device, "ret=%x lkey=%x rkey=%x " | 1187 | ehca_err(&shca->ib_device, "ret=%x lkey=%x rkey=%x " |
diff --git a/drivers/infiniband/hw/ehca/ehca_qp.c b/drivers/infiniband/hw/ehca/ehca_qp.c index 4394123cdbd7..cf3e50ee2d06 100644 --- a/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/drivers/infiniband/hw/ehca/ehca_qp.c | |||
@@ -811,8 +811,8 @@ static int internal_modify_qp(struct ib_qp *ibqp, | |||
811 | unsigned long spl_flags = 0; | 811 | unsigned long spl_flags = 0; |
812 | 812 | ||
813 | /* do query_qp to obtain current attr values */ | 813 | /* do query_qp to obtain current attr values */ |
814 | mqpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL); | 814 | mqpcb = ehca_alloc_fw_ctrlblock(); |
815 | if (mqpcb == NULL) { | 815 | if (!mqpcb) { |
816 | ehca_err(ibqp->device, "Could not get zeroed page for mqpcb " | 816 | ehca_err(ibqp->device, "Could not get zeroed page for mqpcb " |
817 | "ehca_qp=%p qp_num=%x ", my_qp, ibqp->qp_num); | 817 | "ehca_qp=%p qp_num=%x ", my_qp, ibqp->qp_num); |
818 | return -ENOMEM; | 818 | return -ENOMEM; |
@@ -1225,7 +1225,7 @@ modify_qp_exit2: | |||
1225 | } | 1225 | } |
1226 | 1226 | ||
1227 | modify_qp_exit1: | 1227 | modify_qp_exit1: |
1228 | kfree(mqpcb); | 1228 | ehca_free_fw_ctrlblock(mqpcb); |
1229 | 1229 | ||
1230 | return ret; | 1230 | return ret; |
1231 | } | 1231 | } |
@@ -1277,7 +1277,7 @@ int ehca_query_qp(struct ib_qp *qp, | |||
1277 | return -EINVAL; | 1277 | return -EINVAL; |
1278 | } | 1278 | } |
1279 | 1279 | ||
1280 | qpcb = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL ); | 1280 | qpcb = ehca_alloc_fw_ctrlblock(); |
1281 | if (!qpcb) { | 1281 | if (!qpcb) { |
1282 | ehca_err(qp->device,"Out of memory for qpcb " | 1282 | ehca_err(qp->device,"Out of memory for qpcb " |
1283 | "ehca_qp=%p qp_num=%x", my_qp, qp->qp_num); | 1283 | "ehca_qp=%p qp_num=%x", my_qp, qp->qp_num); |
@@ -1401,7 +1401,7 @@ int ehca_query_qp(struct ib_qp *qp, | |||
1401 | ehca_dmp(qpcb, 4*70, "qp_num=%x", qp->qp_num); | 1401 | ehca_dmp(qpcb, 4*70, "qp_num=%x", qp->qp_num); |
1402 | 1402 | ||
1403 | query_qp_exit1: | 1403 | query_qp_exit1: |
1404 | kfree(qpcb); | 1404 | ehca_free_fw_ctrlblock(qpcb); |
1405 | 1405 | ||
1406 | return ret; | 1406 | return ret; |
1407 | } | 1407 | } |
diff --git a/drivers/infiniband/hw/ehca/hipz_hw.h b/drivers/infiniband/hw/ehca/hipz_hw.h index 3fc92b031c50..fad91368dc5a 100644 --- a/drivers/infiniband/hw/ehca/hipz_hw.h +++ b/drivers/infiniband/hw/ehca/hipz_hw.h | |||
@@ -45,6 +45,8 @@ | |||
45 | 45 | ||
46 | #include "ehca_tools.h" | 46 | #include "ehca_tools.h" |
47 | 47 | ||
48 | #define EHCA_MAX_MTU 4 | ||
49 | |||
48 | /* QP Table Entry Memory Map */ | 50 | /* QP Table Entry Memory Map */ |
49 | struct hipz_qptemm { | 51 | struct hipz_qptemm { |
50 | u64 qpx_hcr; | 52 | u64 qpx_hcr; |