aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>2009-09-16 00:37:23 -0400
committerDavid S. Miller <davem@davemloft.net>2009-09-16 23:57:31 -0400
commitd28ecab0c40f587fd1e28701c195747220c984e2 (patch)
treedea63b1eb9ce709790e9fd97cbefd130ed3403b5
parent4c89d86b4df8e4f2cdccb72495e2f4664118ebf1 (diff)
iucv: fix iucv_buffer_cpumask check when calling IUCV functions
Prior to calling IUCV functions, the DECLARE BUFFER function must have been called for at least one CPU to receive IUCV interrupts. With commit "iucv: establish reboot notifier" (6c005961), a check has been introduced to avoid calling IUCV functions if the current CPU does not have an interrupt buffer declared. Because one interrupt buffer is sufficient, change the condition to ensure that one interrupt buffer is available. In addition, checking the buffer on the current CPU creates a race with CPU up/down notifications: before checking the buffer, the IUCV function might be interrupted by an smp_call_function() that retrieves the interrupt buffer for the current CPU. When the IUCV function continues, the check fails and -EIO is returned. If a buffer is available on any other CPU, the IUCV function call must be invoked (instead of failing with -EIO). Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/iucv/iucv.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index aabd2388fcce..8aaa23ccd988 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -864,7 +864,7 @@ int iucv_path_accept(struct iucv_path *path, struct iucv_handler *handler,
864 int rc; 864 int rc;
865 865
866 local_bh_disable(); 866 local_bh_disable();
867 if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { 867 if (cpus_empty(iucv_buffer_cpumask)) {
868 rc = -EIO; 868 rc = -EIO;
869 goto out; 869 goto out;
870 } 870 }
@@ -913,7 +913,7 @@ int iucv_path_connect(struct iucv_path *path, struct iucv_handler *handler,
913 913
914 spin_lock_bh(&iucv_table_lock); 914 spin_lock_bh(&iucv_table_lock);
915 iucv_cleanup_queue(); 915 iucv_cleanup_queue();
916 if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { 916 if (cpus_empty(iucv_buffer_cpumask)) {
917 rc = -EIO; 917 rc = -EIO;
918 goto out; 918 goto out;
919 } 919 }
@@ -973,7 +973,7 @@ int iucv_path_quiesce(struct iucv_path *path, u8 userdata[16])
973 int rc; 973 int rc;
974 974
975 local_bh_disable(); 975 local_bh_disable();
976 if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { 976 if (cpus_empty(iucv_buffer_cpumask)) {
977 rc = -EIO; 977 rc = -EIO;
978 goto out; 978 goto out;
979 } 979 }
@@ -1005,7 +1005,7 @@ int iucv_path_resume(struct iucv_path *path, u8 userdata[16])
1005 int rc; 1005 int rc;
1006 1006
1007 local_bh_disable(); 1007 local_bh_disable();
1008 if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { 1008 if (cpus_empty(iucv_buffer_cpumask)) {
1009 rc = -EIO; 1009 rc = -EIO;
1010 goto out; 1010 goto out;
1011 } 1011 }
@@ -1034,7 +1034,7 @@ int iucv_path_sever(struct iucv_path *path, u8 userdata[16])
1034 int rc; 1034 int rc;
1035 1035
1036 preempt_disable(); 1036 preempt_disable();
1037 if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { 1037 if (cpus_empty(iucv_buffer_cpumask)) {
1038 rc = -EIO; 1038 rc = -EIO;
1039 goto out; 1039 goto out;
1040 } 1040 }
@@ -1068,7 +1068,7 @@ int iucv_message_purge(struct iucv_path *path, struct iucv_message *msg,
1068 int rc; 1068 int rc;
1069 1069
1070 local_bh_disable(); 1070 local_bh_disable();
1071 if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { 1071 if (cpus_empty(iucv_buffer_cpumask)) {
1072 rc = -EIO; 1072 rc = -EIO;
1073 goto out; 1073 goto out;
1074 } 1074 }
@@ -1160,7 +1160,7 @@ int __iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
1160 if (msg->flags & IUCV_IPRMDATA) 1160 if (msg->flags & IUCV_IPRMDATA)
1161 return iucv_message_receive_iprmdata(path, msg, flags, 1161 return iucv_message_receive_iprmdata(path, msg, flags,
1162 buffer, size, residual); 1162 buffer, size, residual);
1163 if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { 1163 if (cpus_empty(iucv_buffer_cpumask)) {
1164 rc = -EIO; 1164 rc = -EIO;
1165 goto out; 1165 goto out;
1166 } 1166 }
@@ -1233,7 +1233,7 @@ int iucv_message_reject(struct iucv_path *path, struct iucv_message *msg)
1233 int rc; 1233 int rc;
1234 1234
1235 local_bh_disable(); 1235 local_bh_disable();
1236 if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { 1236 if (cpus_empty(iucv_buffer_cpumask)) {
1237 rc = -EIO; 1237 rc = -EIO;
1238 goto out; 1238 goto out;
1239 } 1239 }
@@ -1272,7 +1272,7 @@ int iucv_message_reply(struct iucv_path *path, struct iucv_message *msg,
1272 int rc; 1272 int rc;
1273 1273
1274 local_bh_disable(); 1274 local_bh_disable();
1275 if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { 1275 if (cpus_empty(iucv_buffer_cpumask)) {
1276 rc = -EIO; 1276 rc = -EIO;
1277 goto out; 1277 goto out;
1278 } 1278 }
@@ -1322,7 +1322,7 @@ int __iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
1322 union iucv_param *parm; 1322 union iucv_param *parm;
1323 int rc; 1323 int rc;
1324 1324
1325 if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { 1325 if (cpus_empty(iucv_buffer_cpumask)) {
1326 rc = -EIO; 1326 rc = -EIO;
1327 goto out; 1327 goto out;
1328 } 1328 }
@@ -1409,7 +1409,7 @@ int iucv_message_send2way(struct iucv_path *path, struct iucv_message *msg,
1409 int rc; 1409 int rc;
1410 1410
1411 local_bh_disable(); 1411 local_bh_disable();
1412 if (!cpu_isset(smp_processor_id(), iucv_buffer_cpumask)) { 1412 if (cpus_empty(iucv_buffer_cpumask)) {
1413 rc = -EIO; 1413 rc = -EIO;
1414 goto out; 1414 goto out;
1415 } 1415 }