1 /*
2  * Copyright (c) 2011-2017 Cisco Systems, Inc.  All rights reserved
3  * Copyright (c) 2016      Intel, Inc.  All rights reserved.
4  * $COPYRIGHT$
5  *
6  * Additional copyrights may follow
7  *
8  * $HEADER$
9  */
10 
11 
12 #include "opal_config.h"
13 
14 #include "opal/constants.h"
15 
16 #include "opal/mca/hwloc/hwloc-internal.h"
17 #include "opal/mca/hwloc/base/base.h"
18 
19 
20 /*
21  * Don't use show_help() here (or print any error message at all).
22  * Let the upper layer output a relevant message, because doing so may
23  * be complicated (e.g., this might be called from the ORTE ODLS,
24  * which has to do some extra steps to get error messages to be
25  * displayed).
26  */
opal_hwloc_base_set_process_membind_policy(void)27 int opal_hwloc_base_set_process_membind_policy(void)
28 {
29     int rc = 0, flags;
30     hwloc_membind_policy_t policy;
31     hwloc_cpuset_t cpuset;
32 
33     /* Make sure opal_hwloc_topology has been set by the time we've
34        been called */
35     if (OPAL_SUCCESS != opal_hwloc_base_get_topology()) {
36         return OPAL_ERR_BAD_PARAM;
37     }
38 
39     /* Set the default memory allocation policy according to MCA
40        param */
41     switch (opal_hwloc_base_map) {
42     case OPAL_HWLOC_BASE_MAP_LOCAL_ONLY:
43         policy = HWLOC_MEMBIND_BIND;
44         flags = HWLOC_MEMBIND_STRICT;
45         break;
46 
47     case OPAL_HWLOC_BASE_MAP_NONE:
48     default:
49         policy = HWLOC_MEMBIND_DEFAULT;
50         flags = 0;
51         break;
52     }
53 
54     cpuset = hwloc_bitmap_alloc();
55     if (NULL == cpuset) {
56         rc = OPAL_ERR_OUT_OF_RESOURCE;
57     } else {
58         int e;
59         hwloc_get_cpubind(opal_hwloc_topology, cpuset, 0);
60         rc = hwloc_set_membind(opal_hwloc_topology,
61                                cpuset, policy, flags);
62         e = errno;
63         hwloc_bitmap_free(cpuset);
64 
65         /* See if hwloc was able to do it.  If hwloc failed due to
66            ENOSYS, but the base_map == NONE, then it's not really an
67            error. */
68         if (0 != rc && ENOSYS == e &&
69             OPAL_HWLOC_BASE_MAP_NONE == opal_hwloc_base_map) {
70             rc = 0;
71         }
72     }
73 
74     return (0 == rc) ? OPAL_SUCCESS : OPAL_ERROR;
75 }
76 
opal_hwloc_base_memory_set(opal_hwloc_base_memory_segment_t * segments,size_t num_segments)77 int opal_hwloc_base_memory_set(opal_hwloc_base_memory_segment_t *segments,
78                                size_t num_segments)
79 {
80     int rc = OPAL_SUCCESS;
81     char *msg = NULL;
82     size_t i;
83     hwloc_cpuset_t cpuset = NULL;
84 
85     /* bozo check */
86     if (OPAL_SUCCESS != opal_hwloc_base_get_topology()) {
87         msg = "hwloc_set_area_membind() failure - topology not available";
88         return opal_hwloc_base_report_bind_failure(__FILE__, __LINE__,
89                                                    msg, rc);
90     }
91 
92     /* This module won't be used unless the process is already
93        processor-bound.  So find out where we're processor bound, and
94        bind our memory there, too. */
95     cpuset = hwloc_bitmap_alloc();
96     if (NULL == cpuset) {
97         rc = OPAL_ERR_OUT_OF_RESOURCE;
98         msg = "hwloc_bitmap_alloc() failure";
99         goto out;
100     }
101     hwloc_get_cpubind(opal_hwloc_topology, cpuset, 0);
102     for (i = 0; i < num_segments; ++i) {
103         if (0 != hwloc_set_area_membind(opal_hwloc_topology,
104                                         segments[i].mbs_start_addr,
105                                         segments[i].mbs_len, cpuset,
106                                         HWLOC_MEMBIND_BIND,
107                                         HWLOC_MEMBIND_STRICT)) {
108             rc = OPAL_ERROR;
109             msg = "hwloc_set_area_membind() failure";
110             goto out;
111         }
112     }
113 
114  out:
115     if (NULL != cpuset) {
116         hwloc_bitmap_free(cpuset);
117     }
118     if (OPAL_SUCCESS != rc) {
119         return opal_hwloc_base_report_bind_failure(__FILE__, __LINE__, msg, rc);
120     }
121     return OPAL_SUCCESS;
122 }
123 
opal_hwloc_base_node_name_to_id(char * node_name,int * id)124 int opal_hwloc_base_node_name_to_id(char *node_name, int *id)
125 {
126     /* GLB: fix me */
127     *id = atoi(node_name + 3);
128 
129     return OPAL_SUCCESS;
130 }
131 
opal_hwloc_base_membind(opal_hwloc_base_memory_segment_t * segs,size_t count,int node_id)132 int opal_hwloc_base_membind(opal_hwloc_base_memory_segment_t *segs,
133                             size_t count, int node_id)
134 {
135     size_t i;
136     int rc = OPAL_SUCCESS;
137     char *msg = NULL;
138     hwloc_cpuset_t cpuset = NULL;
139 
140     /* bozo check */
141     if (OPAL_SUCCESS != opal_hwloc_base_get_topology()) {
142         msg = "hwloc_set_area_membind() failure - topology not available";
143         return opal_hwloc_base_report_bind_failure(__FILE__, __LINE__,
144                                                    msg, rc);
145     }
146 
147     cpuset = hwloc_bitmap_alloc();
148     if (NULL == cpuset) {
149         rc = OPAL_ERR_OUT_OF_RESOURCE;
150         msg = "hwloc_bitmap_alloc() failure";
151         goto out;
152     }
153     hwloc_bitmap_set(cpuset, node_id);
154     for(i = 0; i < count; i++) {
155         if (0 != hwloc_set_area_membind(opal_hwloc_topology,
156                                         segs[i].mbs_start_addr,
157                                         segs[i].mbs_len, cpuset,
158                                         HWLOC_MEMBIND_BIND,
159                                         HWLOC_MEMBIND_STRICT)) {
160             rc = OPAL_ERROR;
161             msg = "hwloc_set_area_membind() failure";
162             goto out;
163         }
164     }
165 
166  out:
167     if (NULL != cpuset) {
168         hwloc_bitmap_free(cpuset);
169     }
170     if (OPAL_SUCCESS != rc) {
171         return opal_hwloc_base_report_bind_failure(__FILE__, __LINE__, msg, rc);
172     }
173     return OPAL_SUCCESS;
174 }
175