]>
Commit | Line | Data |
---|---|---|
4d1e5b62 AF |
1 | From: Gerald Schaefer <geraldsc@de.ibm.com> |
2 | Subject: zfcp: fix memory alignment for GPN_FT requests. | |
3 | References: bnc#466462 | |
4 | ||
5 | Symptom: An unexpected adapter reopen can be triggered in case | |
6 | of a wrongly aligned GPN_FT nameserver request. | |
7 | Problem: A request which is stored across a page is not allowed. | |
8 | The standard memory allocation does not guarantee to have | |
9 | all requested memory within one page. | |
10 | Solution: Make sure the requested memory is always within one page. | |
11 | ||
12 | Acked-by: John Jolly <jjolly@suse.de> | |
13 | ||
14 | --- | |
15 | drivers/s390/scsi/zfcp_aux.c | 7 +++++++ | |
16 | drivers/s390/scsi/zfcp_def.h | 9 +++++++++ | |
17 | drivers/s390/scsi/zfcp_fc.c | 13 +++---------- | |
18 | 3 files changed, 19 insertions(+), 10 deletions(-) | |
19 | ||
20 | Index: linux-sles11/drivers/s390/scsi/zfcp_aux.c | |
21 | =================================================================== | |
22 | --- linux-sles11.orig/drivers/s390/scsi/zfcp_aux.c | |
23 | +++ linux-sles11/drivers/s390/scsi/zfcp_aux.c | |
24 | @@ -175,6 +175,11 @@ static int __init zfcp_module_init(void) | |
25 | if (!zfcp_data.gid_pn_cache) | |
26 | goto out_gid_cache; | |
27 | ||
28 | + zfcp_data.gpn_ft_cache = zfcp_cache_create( | |
29 | + sizeof(struct ct_iu_gpn_ft_req), "zfcp_gpn"); | |
30 | + if (!zfcp_data.gpn_ft_cache) | |
31 | + goto out_gpn_cache; | |
32 | + | |
33 | zfcp_data.work_queue = create_singlethread_workqueue("zfcp_wq"); | |
34 | ||
35 | INIT_LIST_HEAD(&zfcp_data.adapter_list_head); | |
36 | @@ -209,6 +214,8 @@ out_ccw_register: | |
37 | out_misc: | |
38 | fc_release_transport(zfcp_data.scsi_transport_template); | |
39 | out_transport: | |
40 | + kmem_cache_destroy(zfcp_data.gpn_ft_cache); | |
41 | +out_gpn_cache: | |
42 | kmem_cache_destroy(zfcp_data.gid_pn_cache); | |
43 | out_gid_cache: | |
44 | kmem_cache_destroy(zfcp_data.sr_buffer_cache); | |
45 | Index: linux-sles11/drivers/s390/scsi/zfcp_def.h | |
46 | =================================================================== | |
47 | --- linux-sles11.orig/drivers/s390/scsi/zfcp_def.h | |
48 | +++ linux-sles11/drivers/s390/scsi/zfcp_def.h | |
49 | @@ -333,6 +333,14 @@ struct ct_iu_gid_pn_resp { | |
50 | u32 d_id; | |
51 | } __attribute__ ((packed)); | |
52 | ||
53 | +struct ct_iu_gpn_ft_req { | |
54 | + struct ct_hdr header; | |
55 | + u8 flags; | |
56 | + u8 domain_id_scope; | |
57 | + u8 area_id_scope; | |
58 | + u8 fc4_type; | |
59 | +} __attribute__ ((packed)); | |
60 | + | |
61 | /** | |
62 | * struct zfcp_send_ct - used to pass parameters to function zfcp_fsf_send_ct | |
63 | * @wka_port: port where the request is sent to | |
64 | @@ -595,6 +603,7 @@ struct zfcp_data { | |
65 | struct kmem_cache *fsf_req_qtcb_cache; | |
66 | struct kmem_cache *sr_buffer_cache; | |
67 | struct kmem_cache *gid_pn_cache; | |
68 | + struct kmem_cache *gpn_ft_cache; | |
69 | struct workqueue_struct *work_queue; | |
70 | }; | |
71 | ||
72 | Index: linux-sles11/drivers/s390/scsi/zfcp_fc.c | |
73 | =================================================================== | |
74 | --- linux-sles11.orig/drivers/s390/scsi/zfcp_fc.c | |
75 | +++ linux-sles11/drivers/s390/scsi/zfcp_fc.c | |
76 | @@ -10,14 +10,6 @@ | |
77 | ||
78 | #include "zfcp_ext.h" | |
79 | ||
80 | -struct ct_iu_gpn_ft_req { | |
81 | - struct ct_hdr header; | |
82 | - u8 flags; | |
83 | - u8 domain_id_scope; | |
84 | - u8 area_id_scope; | |
85 | - u8 fc4_type; | |
86 | -} __attribute__ ((packed)); | |
87 | - | |
88 | struct gpn_ft_resp_acc { | |
89 | u8 control; | |
90 | u8 port_id[3]; | |
91 | @@ -450,7 +442,8 @@ static void zfcp_free_sg_env(struct zfcp | |
92 | { | |
93 | struct scatterlist *sg = &gpn_ft->sg_req; | |
94 | ||
95 | - kfree(sg_virt(sg)); /* free request buffer */ | |
96 | + /* free request buffer */ | |
97 | + kmem_cache_free(zfcp_data.gpn_ft_cache, sg_virt(sg)); | |
98 | zfcp_sg_free_table(gpn_ft->sg_resp, buf_num); | |
99 | ||
100 | kfree(gpn_ft); | |
101 | @@ -465,7 +458,7 @@ static struct zfcp_gpn_ft *zfcp_alloc_sg | |
102 | if (!gpn_ft) | |
103 | return NULL; | |
104 | ||
105 | - req = kzalloc(sizeof(struct ct_iu_gpn_ft_req), GFP_KERNEL); | |
106 | + req = kmem_cache_alloc(zfcp_data.gpn_ft_cache, GFP_KERNEL); | |
107 | if (!req) { | |
108 | kfree(gpn_ft); | |
109 | gpn_ft = NULL; |