Skip to content

Commit 4310a25

Browse files
authored
Update system PN string in fan control app. (sonic-net#151)
[platform/fanctrl] Fix daemon crash when the thermal direction is unknown. *Fix pointer uninitialized when the thermal direction is unknown. *If system thermal direction is unknown, set fan speed to 100% and exit program. *Update new F2B system and fans Part-Number.
1 parent bf6b61a commit 4310a25

File tree

1 file changed

+103
-26
lines changed
  • platform/broadcom/sonic-platform-modules-cel/tools/fanctrl

1 file changed

+103
-26
lines changed

platform/broadcom/sonic-platform-modules-cel/tools/fanctrl/fand_v2.c

+103-26
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,9 @@
102102
#define FAN_DIR_FAULT 0
103103
#define FAN_DIR_B2F 1
104104
#define FAN_DIR_F2B 2
105-
#define THERMAL_DIR_F2B_STR "R1241-F0001"
106-
#define THERMAL_DIR_B2F_STR "R1241-F0002"
107-
#define FAN_DIR_F2B_STR "R1241-F9001"
105+
#define THERMAL_DIR_F2B_STR "R1241-F9019-01"
106+
#define THERMAL_DIR_B2F_STR "Undefined"
107+
#define FAN_DIR_F2B_STR "R1241-FN019-013JW"
108108
#define FAN_DIR_B2F_STR "R1241-F9002"
109109
#define DELTA_PSU_DIR_F2B_STR "DPS-1100FB"
110110
#define DELTA_PSU_DIR_B2F_STR "DPS-1100AB"
@@ -140,7 +140,7 @@ static int calculate_fan_one_fail_pwm(int cur_temp, int last_temp);
140140

141141
static int read_temp_sysfs(struct sensor_info_sysfs *sensor);
142142
static int read_temp_directly_sysfs(struct sensor_info_sysfs *sensor);
143-
143+
static void get_direction_str(int direction, char *message);
144144

145145
struct line_policy fishbone48_f2b_normal = {
146146
.temp_hyst = CRITICAL_TEMP_HYST,
@@ -631,6 +631,7 @@ static struct thermal_policy b2f_one_fail_policy = {
631631
.line = &fishbone48_b2f_onefail,
632632
};
633633

634+
/* Global variables */
634635
static struct thermal_policy *policy = NULL;
635636
static int pid_using = 0;
636637
static int direction = FAN_DIR_INIT;
@@ -1211,7 +1212,7 @@ static int alarm_temp_update(int *alarm)
12111212
info->flag &= ~HIGH_MAX_BIT;
12121213
syslog(LOG_INFO, "%s is NORMAL, set fan normal speed", info->name);
12131214
}
1214-
#ifdef DEBU
1215+
#ifdef DEBUG
12151216
syslog(LOG_DEBUG, "[xuth] Major max bit: %d, recovery count: %d", *alarm & HIGH_MAX_BIT ? 1 : 0, info->recovery_count);
12161217
#endif
12171218
}
@@ -1961,6 +1962,17 @@ char* find_sub_string(char *src, const char *sub, int src_len)
19611962
return NULL;
19621963
}
19631964

1965+
/*
1966+
* Determine the system's thermal direction from the fan EEPROMs.
1967+
* If the fans are not all in the same direction, thermal direction will
1968+
* determine by the large majority. If the total number of fan directions
1969+
* are even, assume F2B.
1970+
*
1971+
* This also updates fans status and info in global variable fantray_info[].
1972+
*
1973+
* @param direction System thermal direction.
1974+
* @return fan direction one of FAN_DIR_F2B or FAN_DIR_B2F.
1975+
*/
19641976
static int get_fan_direction(int direction)
19651977
{
19661978
struct fantray_info_stu_sysfs *fantray;
@@ -1972,6 +1984,9 @@ static int get_fan_direction(int direction)
19721984
int i = 0;
19731985
char *pn;
19741986
int ret;
1987+
char direction_str[8];
1988+
1989+
get_direction_str(direction, direction_str);
19751990

19761991
for (; i < TOTAL_FANS + TOTAL_PSUS; i++)
19771992
{
@@ -2007,9 +2022,9 @@ static int get_fan_direction(int direction)
20072022
}
20082023
fantray->direction = FAN_DIR_F2B;
20092024
if (direction != fantray->direction)
2010-
syslog(LOG_ERR, "%s airflow direction mismatch, direction is F2B, system direction is B2F", fantray->name);
2025+
syslog(LOG_ERR, "%s airflow direction mismatch, direction is F2B, system direction is %s", fantray->name, direction_str);
20112026
else
2012-
syslog(LOG_WARNING, "%s airflow direction match, direction is F2B, system direction is F2B", fantray->name);
2027+
syslog(LOG_WARNING, "%s airflow direction match, direction is F2B, system direction is %s", fantray->name, direction_str);
20132028
} else if (find_sub_string(buffer, FAN_DIR_B2F_STR, sizeof(buffer))) {
20142029
r2f_fan_cnt++;
20152030
if (fantray->direction == FAN_DIR_FAULT) {
@@ -2021,9 +2036,9 @@ static int get_fan_direction(int direction)
20212036
}
20222037
fantray->direction = FAN_DIR_B2F;
20232038
if (direction != fantray->direction)
2024-
syslog(LOG_ERR, "%s airflow direction mismatch, direction is B2F, system direction is F2B", fantray->name);
2039+
syslog(LOG_ERR, "%s airflow direction mismatch, direction is B2F, system direction is %s", fantray->name, direction_str);
20252040
else
2026-
syslog(LOG_WARNING, "%s airflow direction match, direction is B2F, system direction is B2F", fantray->name);
2041+
syslog(LOG_WARNING, "%s airflow direction match, direction is B2F, system direction is %s", fantray->name, direction_str);
20272042
} else {
20282043
fantray->direction = FAN_DIR_FAULT;
20292044
if (ret > 0) {
@@ -2044,9 +2059,9 @@ static int get_fan_direction(int direction)
20442059
}
20452060
fantray->direction = FAN_DIR_F2B;
20462061
if (direction != fantray->direction)
2047-
syslog(LOG_ERR, "%s airflow direction mismatch, direction is F2B, system direction is B2F", fantray->name);
2062+
syslog(LOG_ERR, "%s airflow direction mismatch, direction is F2B, system direction is %s", fantray->name, direction_str);
20482063
else
2049-
syslog(LOG_WARNING, "%s airflow direction match, direction is F2B, system direction is F2B", fantray->name);
2064+
syslog(LOG_WARNING, "%s airflow direction match, direction is F2B, system direction is %s", fantray->name, direction_str);
20502065
} else if (find_sub_string(buffer, DELTA_PSU_DIR_B2F_STR, sizeof(buffer))) {
20512066
if (fantray->direction == FAN_DIR_FAULT) {
20522067
syslog(LOG_WARNING, "%s eeprom is NORMAL", fantray->name);
@@ -2057,9 +2072,9 @@ static int get_fan_direction(int direction)
20572072
}
20582073
fantray->direction = FAN_DIR_B2F;
20592074
if (direction != fantray->direction)
2060-
syslog(LOG_ERR, "%s airflow direction mismatch, direction is B2F, system direction is F2B", fantray->name);
2075+
syslog(LOG_ERR, "%s airflow direction mismatch, direction is B2F, system direction is %s", fantray->name, direction_str);
20612076
else
2062-
syslog(LOG_WARNING, "%s airflow direction match, direction is B2F, system direction is B2F", fantray->name);
2077+
syslog(LOG_WARNING, "%s airflow direction match, direction is B2F, system direction is %s", fantray->name, direction_str);
20632078
} else if (find_sub_string(buffer, ACBEL_PSU_DIR_F2B_STR, sizeof(buffer))) {
20642079
if (fantray->direction == FAN_DIR_FAULT) {
20652080
syslog(LOG_WARNING, "%s eeprom is NORMAL", fantray->name);
@@ -2070,9 +2085,9 @@ static int get_fan_direction(int direction)
20702085
}
20712086
fantray->direction = FAN_DIR_F2B;
20722087
if (direction != fantray->direction)
2073-
syslog(LOG_ERR, "%s airflow direction mismatch, direction is F2B, system direction is B2F", fantray->name);
2088+
syslog(LOG_ERR, "%s airflow direction mismatch, direction is F2B, system direction is %s", fantray->name, direction_str);
20742089
else
2075-
syslog(LOG_WARNING, "%s airflow direction match, direction is F2B, system direction is F2B", fantray->name);
2090+
syslog(LOG_WARNING, "%s airflow direction match, direction is F2B, system direction is %s", fantray->name, direction_str);
20762091
} else if (find_sub_string(buffer, ACBEL_PSU_DIR_B2F_STR, sizeof(buffer))) {
20772092
if (fantray->direction == FAN_DIR_FAULT) {
20782093
syslog(LOG_WARNING, "%s eeprom is NORMAL", fantray->name);
@@ -2083,9 +2098,9 @@ static int get_fan_direction(int direction)
20832098
}
20842099
fantray->direction = FAN_DIR_B2F;
20852100
if (direction != fantray->direction)
2086-
syslog(LOG_ERR, "%s airflow direction mismatch, direction is B2F, system direction is F2B", fantray->name);
2101+
syslog(LOG_ERR, "%s airflow direction mismatch, direction is B2F, system direction is %s", fantray->name, direction_str);
20872102
else
2088-
syslog(LOG_WARNING, "%s airflow direction match, direction is B2F, system direction is B2F", fantray->name);
2103+
syslog(LOG_WARNING, "%s airflow direction match, direction is B2F, system direction is %s", fantray->name, direction_str);
20892104
} else {
20902105
fantray->direction = FAN_DIR_FAULT;
20912106
if (ret > 0) {
@@ -2106,6 +2121,13 @@ static int get_fan_direction(int direction)
21062121
}
21072122
}
21082123

2124+
/*
2125+
* Get system thermal direction from TLV EEPROM.
2126+
* If falis to read thermal direction, then set the fan speed to maximum.
2127+
*
2128+
* @return the systen thermal direction FAN_DIR_F2B or FAN_DIR_B2F or less than
2129+
* zero if cannot determine the system thermal direction.
2130+
*/
21092131
int get_thermal_direction(void)
21102132
{
21112133
char buffer[128];
@@ -2114,43 +2136,74 @@ int get_thermal_direction(void)
21142136
memset(command, 0, sizeof(command));
21152137
sprintf(command, "/usr/bin/decode-syseeprom | grep 'Part Number' 2> /dev/null");
21162138
fp = popen(command, "r");
2117-
int thermal_dir;
2139+
int thermal_dir = FAN_DIR_INIT;
21182140
int fan, fan_speed;
21192141

2142+
/* We have 2 possible errors here
2143+
* 1: The eeprom canot be read
2144+
* 2: The PN does not match any expected cases
2145+
* Both will comes to the conclusion that we cannot know the system
2146+
* thermal direction here.
2147+
*
2148+
* We can do either let the fan be 100% and STOP PID control OR
2149+
* determine the fan speed from the fans and let running.
2150+
* But this might cause the program continue running with incorrect
2151+
* thermal parameter.
2152+
*
2153+
* I perfer to go with 100% and exit. The service can be started again,
2154+
* after the issue is fixed.
2155+
*/
2156+
21202157
if (!fp) {
2121-
syslog(LOG_ERR, "failed to get thermal direction");
2122-
syslog(LOG_WARNING, "thermal direction judged by fan direction");
2158+
syslog(LOG_ERR, "failed to read thermal direction from TLV EEPROM, FAN speed is set to 100%%");
2159+
fan_speed = FAN_MAX;
2160+
for (fan = 0; fan < TOTAL_FANS; fan++) {
2161+
write_fan_speed(fan, fan_speed);
2162+
}
2163+
write_psu_fan_speed(fan, fan_speed);
21232164
} else {
21242165
char temp;
21252166
int len = 0;
21262167
memset(buffer, 0, sizeof(buffer));
21272168
fread(buffer, sizeof(char), sizeof(buffer), fp);
21282169
pclose(fp);
21292170
if (find_sub_string(buffer, THERMAL_DIR_F2B_STR, sizeof(buffer))) {
2130-
syslog(LOG_INFO, "system direction is F2B");
2171+
syslog(LOG_INFO, "system thermal direction is F2B");
21312172
thermal_dir = FAN_DIR_F2B;
21322173
} else if (find_sub_string(buffer, THERMAL_DIR_B2F_STR, sizeof(buffer))) {
2133-
syslog(LOG_INFO, "system direction is B2F");
2174+
syslog(LOG_INFO, "system thermal direction is B2F");
21342175
thermal_dir = FAN_DIR_B2F;
21352176
} else {
2136-
syslog(LOG_ERR, "system direction is unknown, FAN speed is set to 100%%");
2177+
syslog(LOG_ERR, "unrecognized system P/N in TLV EEPROM\n");
2178+
syslog(LOG_ERR, "system thermal direction is unknown, FAN speed is set to 100%%");
21372179
fan_speed = FAN_MAX;
21382180
for (fan = 0; fan < TOTAL_FANS; fan++) {
21392181
write_fan_speed(fan, fan_speed);
21402182
}
21412183
write_psu_fan_speed(fan, fan_speed);
21422184
}
21432185
}
2186+
21442187
get_fan_direction(thermal_dir);
21452188

21462189
return thermal_dir;
21472190
}
21482191

2149-
static void update_thermal_direction()
2192+
static int update_thermal_direction()
21502193
{
21512194
struct fantray_info_stu_sysfs *fantray;
21522195
int dir = get_thermal_direction();
2196+
2197+
/* Just pop out with error code, if error happen */
2198+
if (dir < 0)
2199+
return dir;
2200+
21532201
if (direction != dir) {
2202+
/*
2203+
* This line only called once. Even the function name is update.
2204+
* If the thermal direction is not set, the whole program will
2205+
* runs into unexpected behaviors.
2206+
*/
21542207
direction = dir;
21552208
if (direction == FAN_DIR_F2B) {
21562209
syslog(LOG_INFO, "setting F2B thermal policy");
@@ -2161,6 +2214,7 @@ static void update_thermal_direction()
21612214
policy = &b2f_normal_policy;
21622215
}
21632216
}
2217+
return 0;
21642218
}
21652219

21662220
static int pid_ini_parser(struct board_info_stu_sysfs *info, FILE *fp)
@@ -2263,8 +2317,16 @@ static int load_pid_config(void)
22632317
static int policy_init(void)
22642318
{
22652319
int slope;
2320+
int ret;
22662321
syslog(LOG_NOTICE, "Initializing FSC policy");
2267-
update_thermal_direction();
2322+
2323+
ret = update_thermal_direction();
2324+
2325+
if (ret < 0){
2326+
syslog(LOG_NOTICE, "Failed, Unknown thermal direction");
2327+
syslog(LOG_NOTICE, "Trying to exit...");
2328+
return ret;
2329+
}
22682330

22692331
load_pid_config();
22702332
if (pid_using == 0) {
@@ -2288,7 +2350,18 @@ static int policy_init(void)
22882350
return 0;
22892351
}
22902352

2353+
static void get_direction_str(int direction, char *message)
2354+
{
2355+
const char *airflow_strings[] = { "Unknown",
2356+
"Fault",
2357+
"B2F",
2358+
"F2B"};
2359+
2360+
strcpy( message, airflow_strings[ direction + 1] );
2361+
}
2362+
22912363
int main(int argc, char **argv) {
2364+
int ret;
22922365
int critical_temp;
22932366
int old_temp = -1;
22942367
struct fantray_info_stu_sysfs *info;
@@ -2324,7 +2397,11 @@ int main(int argc, char **argv) {
23242397
daemon(1, 0);
23252398
syslog(LOG_DEBUG, "Starting up; system should have %d fans.", TOTAL_FANS);
23262399
fancpld_watchdog_enable();
2327-
policy_init();
2400+
ret = policy_init();
2401+
if (ret < 0){
2402+
syslog(LOG_NOTICE, "exit");
2403+
return ret;
2404+
}
23282405
sleep(5); /* Give the fans time to come up to speed */
23292406
while (1) {
23302407
fan_speed_temp = 0;

0 commit comments

Comments
 (0)