aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorJack Morgenstein <jackm@dev.mellanox.co.il>2010-10-04 08:11:34 -0400
committerRoland Dreier <rolandd@cisco.com>2010-10-23 16:53:09 -0400
commitd0d68b8693bd16bfbbc93b89f1d9f3351723307c (patch)
tree805552db83354bff13841e523e502a0e689d1643 /drivers/infiniband
parent5a0fd09428e47fb08d5a887515d92bb2447f4b65 (diff)
IB/mlx4: Signal node desc changes to SM by using FW to generate trap 144
The Node Description cannot be changed via MADs (it is read-only). Until now, it was changed in the driver via sysfs, and the new Node Description was simply inserted by the driver into MAD responses (replacing the description returned by FW). System startup scripts use the sysfs interface to change the node description at driver startup to show the hostname, etc. However, this has a race condition: the SM could discover the original FW node description rather than the system-specific description if it queried the port before the startup scripts finish running. For mlx4, we fix this with a new FW command (SET_NODE) that allows passing the new node description to FW. When this command is invoked, FW sends a trap 144 to the SM. When it gets this trap, the SM can query the node to obtain the new node description -- thus eliminating the effects of the race. This patch simply calls SET_NODE command when a new node description is entered via sysfs (thus causing trap 144 to be issued by the FW). We ignore all failures of the SET_NODE command (including those caused by using a device FW that predates the SET_NODE command), since in that case things work just as before. Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/mlx4/main.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index 62e8cd6f0371..ac6951d99336 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -272,14 +272,32 @@ out:
272static int mlx4_ib_modify_device(struct ib_device *ibdev, int mask, 272static int mlx4_ib_modify_device(struct ib_device *ibdev, int mask,
273 struct ib_device_modify *props) 273 struct ib_device_modify *props)
274{ 274{
275 struct mlx4_cmd_mailbox *mailbox;
276
275 if (mask & ~IB_DEVICE_MODIFY_NODE_DESC) 277 if (mask & ~IB_DEVICE_MODIFY_NODE_DESC)
276 return -EOPNOTSUPP; 278 return -EOPNOTSUPP;
277 279
278 if (mask & IB_DEVICE_MODIFY_NODE_DESC) { 280 if (!(mask & IB_DEVICE_MODIFY_NODE_DESC))
279 spin_lock(&to_mdev(ibdev)->sm_lock); 281 return 0;
280 memcpy(ibdev->node_desc, props->node_desc, 64); 282
281 spin_unlock(&to_mdev(ibdev)->sm_lock); 283 spin_lock(&to_mdev(ibdev)->sm_lock);
282 } 284 memcpy(ibdev->node_desc, props->node_desc, 64);
285 spin_unlock(&to_mdev(ibdev)->sm_lock);
286
287 /*
288 * If possible, pass node desc to FW, so it can generate
289 * a 144 trap. If cmd fails, just ignore.
290 */
291 mailbox = mlx4_alloc_cmd_mailbox(to_mdev(ibdev)->dev);
292 if (IS_ERR(mailbox))
293 return 0;
294
295 memset(mailbox->buf, 0, 256);
296 memcpy(mailbox->buf, props->node_desc, 64);
297 mlx4_cmd(to_mdev(ibdev)->dev, mailbox->dma, 1, 0,
298 MLX4_CMD_SET_NODE, MLX4_CMD_TIME_CLASS_A);
299
300 mlx4_free_cmd_mailbox(to_mdev(ibdev)->dev, mailbox);
283 301
284 return 0; 302 return 0;
285} 303}