1 /* 2 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: qdf_mem 22 * This file provides OS dependent memory management APIs 23 */ 24 25 #include "qdf_debugfs.h" 26 #include "qdf_mem.h" 27 #include "qdf_nbuf.h" 28 #include "qdf_lock.h" 29 #include "qdf_mc_timer.h" 30 #include "qdf_module.h" 31 #include <qdf_trace.h> 32 #include "qdf_str.h" 33 #include "qdf_talloc.h" 34 #include <linux/debugfs.h> 35 #include <linux/seq_file.h> 36 #include <linux/string.h> 37 #include <qdf_list.h> 38 39 #ifdef CNSS_MEM_PRE_ALLOC 40 #ifdef CONFIG_CNSS_OUT_OF_TREE 41 #include "cnss_prealloc.h" 42 #else 43 #include <net/cnss_prealloc.h> 44 #endif 45 #endif 46 47 #if defined(MEMORY_DEBUG) || defined(NBUF_MEMORY_DEBUG) 48 static bool mem_debug_disabled; 49 qdf_declare_param(mem_debug_disabled, bool); 50 #endif 51 52 #ifdef MEMORY_DEBUG 53 static bool is_initial_mem_debug_disabled; 54 #endif 55 56 /* Preprocessor Definitions and Constants */ 57 #define QDF_MEM_MAX_MALLOC (4096 * 1024) /* 4 Mega Bytes */ 58 #define QDF_MEM_WARN_THRESHOLD 300 /* ms */ 59 #define QDF_DEBUG_STRING_SIZE 512 60 61 /** 62 * struct __qdf_mem_stat - qdf memory statistics 63 * @kmalloc: total kmalloc allocations 64 * @dma: total dma allocations 65 * @skb: total skb allocations 66 * @skb_total: total skb allocations in host driver 67 * @dp_tx_skb: total Tx skb allocations in datapath 68 * @dp_rx_skb: total Rx skb allocations in datapath 69 * @skb_mem_max: high watermark for skb allocations 70 * @dp_tx_skb_mem_max: high watermark for Tx DP skb allocations 71 * @dp_rx_skb_mem_max: high watermark for Rx DP skb allocations 72 * @dp_tx_skb_count: DP Tx buffer count 73 * @dp_tx_skb_count_max: High watermark for DP Tx buffer count 74 * @dp_rx_skb_count: DP Rx buffer count 75 * @dp_rx_skb_count_max: High watermark for DP Rx buffer count 76 * @tx_descs_outstanding: Current pending Tx descs count 77 * @tx_descs_max: High watermark for pending Tx descs count 78 */ 79 static struct __qdf_mem_stat { 80 qdf_atomic_t kmalloc; 81 qdf_atomic_t dma; 82 qdf_atomic_t skb; 83 qdf_atomic_t skb_total; 84 qdf_atomic_t dp_tx_skb; 85 qdf_atomic_t dp_rx_skb; 86 int32_t skb_mem_max; 87 int32_t dp_tx_skb_mem_max; 88 int32_t dp_rx_skb_mem_max; 89 qdf_atomic_t dp_tx_skb_count; 90 int32_t dp_tx_skb_count_max; 91 qdf_atomic_t dp_rx_skb_count; 92 int32_t dp_rx_skb_count_max; 93 qdf_atomic_t tx_descs_outstanding; 94 int32_t tx_descs_max; 95 } qdf_mem_stat; 96 97 #ifdef MEMORY_DEBUG 98 #include "qdf_debug_domain.h" 99 100 enum list_type { 101 LIST_TYPE_MEM = 0, 102 LIST_TYPE_DMA = 1, 103 LIST_TYPE_NBUF = 2, 104 LIST_TYPE_MAX, 105 }; 106 107 /** 108 * struct major_alloc_priv - private data registered to debugfs entry 109 * created to list the list major allocations 110 * @type: type of the list to be parsed 111 * @threshold: configured by user by overwriting the respective debugfs 112 * sys entry. This is to list the functions which requested 113 * memory/dma allocations more than threshold number of times. 114 */ 115 struct major_alloc_priv { 116 enum list_type type; 117 uint32_t threshold; 118 }; 119 120 static qdf_list_t qdf_mem_domains[QDF_DEBUG_DOMAIN_COUNT]; 121 static qdf_spinlock_t qdf_mem_list_lock; 122 123 static qdf_list_t qdf_mem_dma_domains[QDF_DEBUG_DOMAIN_COUNT]; 124 static qdf_spinlock_t qdf_mem_dma_list_lock; 125 qdf_mem_list_get(enum qdf_debug_domain domain)126 static inline qdf_list_t *qdf_mem_list_get(enum qdf_debug_domain domain) 127 { 128 return &qdf_mem_domains[domain]; 129 } 130 qdf_mem_dma_list(enum qdf_debug_domain domain)131 static inline qdf_list_t *qdf_mem_dma_list(enum qdf_debug_domain domain) 132 { 133 return &qdf_mem_dma_domains[domain]; 134 } 135 136 /** 137 * struct qdf_mem_header - memory object to dubug 138 * @node: node to the list 139 * @domain: the active memory domain at time of allocation 140 * @freed: flag set during free, used to detect double frees 141 * Use uint8_t so we can detect corruption 142 * @func: name of the function the allocation was made from 143 * @line: line number of the file the allocation was made from 144 * @size: size of the allocation in bytes 145 * @caller: Caller of the function for which memory is allocated 146 * @header: a known value, used to detect out-of-bounds access 147 * @time: timestamp at which allocation was made 148 */ 149 struct qdf_mem_header { 150 qdf_list_node_t node; 151 enum qdf_debug_domain domain; 152 uint8_t freed; 153 char func[QDF_MEM_FUNC_NAME_SIZE]; 154 uint32_t line; 155 uint32_t size; 156 void *caller; 157 uint64_t header; 158 uint64_t time; 159 }; 160 161 /* align the qdf_mem_header to 8 bytes */ 162 #define QDF_DMA_MEM_HEADER_ALIGN 8 163 164 static uint64_t WLAN_MEM_HEADER = 0x6162636465666768; 165 static uint64_t WLAN_MEM_TRAILER = 0x8081828384858687; 166 qdf_mem_get_header(void * ptr)167 static inline struct qdf_mem_header *qdf_mem_get_header(void *ptr) 168 { 169 return (struct qdf_mem_header *)ptr - 1; 170 } 171 172 /* make sure the header pointer is 8bytes aligned */ qdf_mem_dma_get_header(void * ptr,qdf_size_t size)173 static inline struct qdf_mem_header *qdf_mem_dma_get_header(void *ptr, 174 qdf_size_t size) 175 { 176 return (struct qdf_mem_header *) 177 qdf_roundup((size_t)((uint8_t *)ptr + size), 178 QDF_DMA_MEM_HEADER_ALIGN); 179 } 180 qdf_mem_get_trailer(struct qdf_mem_header * header)181 static inline uint64_t *qdf_mem_get_trailer(struct qdf_mem_header *header) 182 { 183 return (uint64_t *)((void *)(header + 1) + header->size); 184 } 185 qdf_mem_get_ptr(struct qdf_mem_header * header)186 static inline void *qdf_mem_get_ptr(struct qdf_mem_header *header) 187 { 188 return (void *)(header + 1); 189 } 190 191 /* number of bytes needed for the qdf memory debug information */ 192 #define QDF_MEM_DEBUG_SIZE \ 193 (sizeof(struct qdf_mem_header) + sizeof(WLAN_MEM_TRAILER)) 194 195 /* number of bytes needed for the qdf dma memory debug information */ 196 #define QDF_DMA_MEM_DEBUG_SIZE \ 197 (sizeof(struct qdf_mem_header) + QDF_DMA_MEM_HEADER_ALIGN) 198 qdf_mem_trailer_init(struct qdf_mem_header * header)199 static void qdf_mem_trailer_init(struct qdf_mem_header *header) 200 { 201 QDF_BUG(header); 202 if (!header) 203 return; 204 *qdf_mem_get_trailer(header) = WLAN_MEM_TRAILER; 205 } 206 qdf_mem_header_init(struct qdf_mem_header * header,qdf_size_t size,const char * func,uint32_t line,void * caller)207 static void qdf_mem_header_init(struct qdf_mem_header *header, qdf_size_t size, 208 const char *func, uint32_t line, void *caller) 209 { 210 QDF_BUG(header); 211 if (!header) 212 return; 213 214 header->domain = qdf_debug_domain_get(); 215 header->freed = false; 216 217 qdf_str_lcopy(header->func, func, QDF_MEM_FUNC_NAME_SIZE); 218 219 header->line = line; 220 header->size = size; 221 header->caller = caller; 222 header->header = WLAN_MEM_HEADER; 223 header->time = qdf_get_log_timestamp(); 224 } 225 226 enum qdf_mem_validation_bitmap { 227 QDF_MEM_BAD_HEADER = 1 << 0, 228 QDF_MEM_BAD_TRAILER = 1 << 1, 229 QDF_MEM_BAD_SIZE = 1 << 2, 230 QDF_MEM_DOUBLE_FREE = 1 << 3, 231 QDF_MEM_BAD_FREED = 1 << 4, 232 QDF_MEM_BAD_NODE = 1 << 5, 233 QDF_MEM_BAD_DOMAIN = 1 << 6, 234 QDF_MEM_WRONG_DOMAIN = 1 << 7, 235 }; 236 237 static enum qdf_mem_validation_bitmap qdf_mem_trailer_validate(struct qdf_mem_header * header)238 qdf_mem_trailer_validate(struct qdf_mem_header *header) 239 { 240 enum qdf_mem_validation_bitmap error_bitmap = 0; 241 242 if (*qdf_mem_get_trailer(header) != WLAN_MEM_TRAILER) 243 error_bitmap |= QDF_MEM_BAD_TRAILER; 244 return error_bitmap; 245 } 246 247 static enum qdf_mem_validation_bitmap qdf_mem_header_validate(struct qdf_mem_header * header,enum qdf_debug_domain domain)248 qdf_mem_header_validate(struct qdf_mem_header *header, 249 enum qdf_debug_domain domain) 250 { 251 enum qdf_mem_validation_bitmap error_bitmap = 0; 252 253 if (header->header != WLAN_MEM_HEADER) 254 error_bitmap |= QDF_MEM_BAD_HEADER; 255 256 if (header->size > QDF_MEM_MAX_MALLOC) 257 error_bitmap |= QDF_MEM_BAD_SIZE; 258 259 if (header->freed == true) 260 error_bitmap |= QDF_MEM_DOUBLE_FREE; 261 else if (header->freed) 262 error_bitmap |= QDF_MEM_BAD_FREED; 263 264 if (!qdf_list_node_in_any_list(&header->node)) 265 error_bitmap |= QDF_MEM_BAD_NODE; 266 267 if (header->domain < QDF_DEBUG_DOMAIN_INIT || 268 header->domain >= QDF_DEBUG_DOMAIN_COUNT) 269 error_bitmap |= QDF_MEM_BAD_DOMAIN; 270 else if (header->domain != domain) 271 error_bitmap |= QDF_MEM_WRONG_DOMAIN; 272 273 return error_bitmap; 274 } 275 276 static void qdf_mem_header_assert_valid(struct qdf_mem_header * header,enum qdf_debug_domain current_domain,enum qdf_mem_validation_bitmap error_bitmap,const char * func,uint32_t line)277 qdf_mem_header_assert_valid(struct qdf_mem_header *header, 278 enum qdf_debug_domain current_domain, 279 enum qdf_mem_validation_bitmap error_bitmap, 280 const char *func, 281 uint32_t line) 282 { 283 if (!error_bitmap) 284 return; 285 286 if (error_bitmap & QDF_MEM_BAD_HEADER) 287 qdf_err("Corrupted memory header 0x%llx (expected 0x%llx)", 288 header->header, WLAN_MEM_HEADER); 289 290 if (error_bitmap & QDF_MEM_BAD_SIZE) 291 qdf_err("Corrupted memory size %u (expected < %d)", 292 header->size, QDF_MEM_MAX_MALLOC); 293 294 if (error_bitmap & QDF_MEM_BAD_TRAILER) 295 qdf_err("Corrupted memory trailer 0x%llx (expected 0x%llx)", 296 *qdf_mem_get_trailer(header), WLAN_MEM_TRAILER); 297 298 if (error_bitmap & QDF_MEM_DOUBLE_FREE) 299 qdf_err("Memory has previously been freed"); 300 301 if (error_bitmap & QDF_MEM_BAD_FREED) 302 qdf_err("Corrupted memory freed flag 0x%x", header->freed); 303 304 if (error_bitmap & QDF_MEM_BAD_NODE) 305 qdf_err("Corrupted memory header node or double free"); 306 307 if (error_bitmap & QDF_MEM_BAD_DOMAIN) 308 qdf_err("Corrupted memory domain 0x%x", header->domain); 309 310 if (error_bitmap & QDF_MEM_WRONG_DOMAIN) 311 qdf_err("Memory domain mismatch; allocated:%s(%d), current:%s(%d)", 312 qdf_debug_domain_name(header->domain), header->domain, 313 qdf_debug_domain_name(current_domain), current_domain); 314 315 QDF_MEMDEBUG_PANIC("Fatal memory error detected @ %s:%d", func, line); 316 } 317 318 /** 319 * struct __qdf_mem_info - memory statistics 320 * @func: the function which allocated memory 321 * @line: the line at which allocation happened 322 * @size: the size of allocation 323 * @caller: Address of the caller function 324 * @count: how many allocations of same type 325 * @time: timestamp at which allocation happened 326 */ 327 struct __qdf_mem_info { 328 char func[QDF_MEM_FUNC_NAME_SIZE]; 329 uint32_t line; 330 uint32_t size; 331 void *caller; 332 uint32_t count; 333 uint64_t time; 334 }; 335 336 /* 337 * The table depth defines the de-duplication proximity scope. 338 * A deeper table takes more time, so choose any optimum value. 339 */ 340 #define QDF_MEM_STAT_TABLE_SIZE 8 341 342 /** 343 * qdf_mem_debug_print_header() - memory debug header print logic 344 * @print: the print adapter function 345 * @print_priv: the private data to be consumed by @print 346 * @threshold: the threshold value set by user to list top allocations 347 * 348 * Return: None 349 */ qdf_mem_debug_print_header(qdf_abstract_print print,void * print_priv,uint32_t threshold)350 static void qdf_mem_debug_print_header(qdf_abstract_print print, 351 void *print_priv, 352 uint32_t threshold) 353 { 354 if (threshold) 355 print(print_priv, "APIs requested allocations >= %u no of time", 356 threshold); 357 print(print_priv, 358 "--------------------------------------------------------------"); 359 print(print_priv, 360 " count size total filename caller timestamp"); 361 print(print_priv, 362 "--------------------------------------------------------------"); 363 } 364 365 /** 366 * qdf_mem_meta_table_insert() - insert memory metadata into the given table 367 * @table: the memory metadata table to insert into 368 * @meta: the memory metadata to insert 369 * 370 * Return: true if the table is full after inserting, false otherwise 371 */ qdf_mem_meta_table_insert(struct __qdf_mem_info * table,struct qdf_mem_header * meta)372 static bool qdf_mem_meta_table_insert(struct __qdf_mem_info *table, 373 struct qdf_mem_header *meta) 374 { 375 int i; 376 377 for (i = 0; i < QDF_MEM_STAT_TABLE_SIZE; i++) { 378 if (!table[i].count) { 379 qdf_str_lcopy(table[i].func, meta->func, 380 QDF_MEM_FUNC_NAME_SIZE); 381 table[i].line = meta->line; 382 table[i].size = meta->size; 383 table[i].count = 1; 384 table[i].caller = meta->caller; 385 table[i].time = meta->time; 386 break; 387 } 388 389 if (qdf_str_eq(table[i].func, meta->func) && 390 table[i].line == meta->line && 391 table[i].size == meta->size && 392 table[i].caller == meta->caller) { 393 table[i].count++; 394 break; 395 } 396 } 397 398 /* return true if the table is now full */ 399 return i >= QDF_MEM_STAT_TABLE_SIZE - 1; 400 } 401 402 /** 403 * qdf_mem_domain_print() - output agnostic memory domain print logic 404 * @domain: the memory domain to print 405 * @print: the print adapter function 406 * @print_priv: the private data to be consumed by @print 407 * @threshold: the threshold value set by uset to list top allocations 408 * @mem_print: pointer to function which prints the memory allocation data 409 * 410 * Return: None 411 */ qdf_mem_domain_print(qdf_list_t * domain,qdf_abstract_print print,void * print_priv,uint32_t threshold,void (* mem_print)(struct __qdf_mem_info *,qdf_abstract_print,void *,uint32_t))412 static void qdf_mem_domain_print(qdf_list_t *domain, 413 qdf_abstract_print print, 414 void *print_priv, 415 uint32_t threshold, 416 void (*mem_print)(struct __qdf_mem_info *, 417 qdf_abstract_print, 418 void *, uint32_t)) 419 { 420 QDF_STATUS status; 421 struct __qdf_mem_info table[QDF_MEM_STAT_TABLE_SIZE]; 422 qdf_list_node_t *node; 423 424 qdf_mem_zero(table, sizeof(table)); 425 qdf_mem_debug_print_header(print, print_priv, threshold); 426 427 /* hold lock while inserting to avoid use-after free of the metadata */ 428 qdf_spin_lock(&qdf_mem_list_lock); 429 status = qdf_list_peek_front(domain, &node); 430 while (QDF_IS_STATUS_SUCCESS(status)) { 431 struct qdf_mem_header *meta = (struct qdf_mem_header *)node; 432 bool is_full = qdf_mem_meta_table_insert(table, meta); 433 434 qdf_spin_unlock(&qdf_mem_list_lock); 435 436 if (is_full) { 437 (*mem_print)(table, print, print_priv, threshold); 438 qdf_mem_zero(table, sizeof(table)); 439 } 440 441 qdf_spin_lock(&qdf_mem_list_lock); 442 status = qdf_list_peek_next(domain, node, &node); 443 } 444 qdf_spin_unlock(&qdf_mem_list_lock); 445 446 (*mem_print)(table, print, print_priv, threshold); 447 } 448 449 /** 450 * qdf_mem_meta_table_print() - memory metadata table print logic 451 * @table: the memory metadata table to print 452 * @print: the print adapter function 453 * @print_priv: the private data to be consumed by @print 454 * @threshold: the threshold value set by user to list top allocations 455 * 456 * Return: None 457 */ qdf_mem_meta_table_print(struct __qdf_mem_info * table,qdf_abstract_print print,void * print_priv,uint32_t threshold)458 static void qdf_mem_meta_table_print(struct __qdf_mem_info *table, 459 qdf_abstract_print print, 460 void *print_priv, 461 uint32_t threshold) 462 { 463 int i; 464 char debug_str[QDF_DEBUG_STRING_SIZE]; 465 size_t len = 0; 466 char *debug_prefix = "WLAN_BUG_RCA: memory leak detected"; 467 468 len += qdf_scnprintf(debug_str, sizeof(debug_str) - len, 469 "%s", debug_prefix); 470 471 for (i = 0; i < QDF_MEM_STAT_TABLE_SIZE; i++) { 472 if (!table[i].count) 473 break; 474 475 print(print_priv, 476 "%6u x %5u = %7uB @ %s:%u %pS %llu", 477 table[i].count, 478 table[i].size, 479 table[i].count * table[i].size, 480 table[i].func, 481 table[i].line, table[i].caller, 482 table[i].time); 483 len += qdf_scnprintf(debug_str + len, 484 sizeof(debug_str) - len, 485 " @ %s:%u %pS", 486 table[i].func, 487 table[i].line, 488 table[i].caller); 489 } 490 print(print_priv, "%s", debug_str); 491 } 492 qdf_err_printer(void * priv,const char * fmt,...)493 static int qdf_err_printer(void *priv, const char *fmt, ...) 494 { 495 va_list args; 496 497 va_start(args, fmt); 498 QDF_VTRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, (char *)fmt, args); 499 va_end(args); 500 501 return 0; 502 } 503 504 #endif /* MEMORY_DEBUG */ 505 506 bool prealloc_disabled = 1; 507 qdf_declare_param(prealloc_disabled, bool); 508 qdf_export_symbol(prealloc_disabled); 509 qdf_mem_malloc_flags(void)510 int qdf_mem_malloc_flags(void) 511 { 512 if (in_interrupt() || !preemptible() || rcu_preempt_depth()) 513 return GFP_ATOMIC; 514 515 return GFP_KERNEL; 516 } 517 518 qdf_export_symbol(qdf_mem_malloc_flags); 519 qdf_prealloc_disabled_config_get(void)520 bool qdf_prealloc_disabled_config_get(void) 521 { 522 return prealloc_disabled; 523 } 524 525 qdf_export_symbol(qdf_prealloc_disabled_config_get); 526 527 #ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI qdf_prealloc_disabled_config_set(const char * str_value)528 QDF_STATUS qdf_prealloc_disabled_config_set(const char *str_value) 529 { 530 QDF_STATUS status; 531 532 status = qdf_bool_parse(str_value, &prealloc_disabled); 533 return status; 534 } 535 #endif 536 537 #if defined WLAN_DEBUGFS 538 539 /* Debugfs root directory for qdf_mem */ 540 static struct dentry *qdf_mem_debugfs_root; 541 542 #ifdef MEMORY_DEBUG seq_printf_printer(void * priv,const char * fmt,...)543 static int seq_printf_printer(void *priv, const char *fmt, ...) 544 { 545 struct seq_file *file = priv; 546 va_list args; 547 548 va_start(args, fmt); 549 seq_vprintf(file, fmt, args); 550 seq_puts(file, "\n"); 551 va_end(args); 552 553 return 0; 554 } 555 556 /** 557 * qdf_print_major_alloc() - memory metadata table print logic 558 * @table: the memory metadata table to print 559 * @print: the print adapter function 560 * @print_priv: the private data to be consumed by @print 561 * @threshold: the threshold value set by uset to list top allocations 562 * 563 * Return: None 564 */ qdf_print_major_alloc(struct __qdf_mem_info * table,qdf_abstract_print print,void * print_priv,uint32_t threshold)565 static void qdf_print_major_alloc(struct __qdf_mem_info *table, 566 qdf_abstract_print print, 567 void *print_priv, 568 uint32_t threshold) 569 { 570 int i; 571 572 for (i = 0; i < QDF_MEM_STAT_TABLE_SIZE; i++) { 573 if (!table[i].count) 574 break; 575 if (table[i].count >= threshold) 576 print(print_priv, 577 "%6u x %5u = %7uB @ %s:%u %pS %llu", 578 table[i].count, 579 table[i].size, 580 table[i].count * table[i].size, 581 table[i].func, 582 table[i].line, table[i].caller, 583 table[i].time); 584 } 585 } 586 587 /** 588 * qdf_mem_seq_start() - sequential callback to start 589 * @seq: seq_file handle 590 * @pos: The start position of the sequence 591 * 592 * Return: iterator pointer, or NULL if iteration is complete 593 */ qdf_mem_seq_start(struct seq_file * seq,loff_t * pos)594 static void *qdf_mem_seq_start(struct seq_file *seq, loff_t *pos) 595 { 596 enum qdf_debug_domain domain = *pos; 597 598 if (!qdf_debug_domain_valid(domain)) 599 return NULL; 600 601 /* just use the current position as our iterator */ 602 return pos; 603 } 604 605 /** 606 * qdf_mem_seq_next() - next sequential callback 607 * @seq: seq_file handle 608 * @v: the current iterator 609 * @pos: the current position 610 * 611 * Get the next node and release previous node. 612 * 613 * Return: iterator pointer, or NULL if iteration is complete 614 */ qdf_mem_seq_next(struct seq_file * seq,void * v,loff_t * pos)615 static void *qdf_mem_seq_next(struct seq_file *seq, void *v, loff_t *pos) 616 { 617 ++*pos; 618 619 return qdf_mem_seq_start(seq, pos); 620 } 621 622 /** 623 * qdf_mem_seq_stop() - stop sequential callback 624 * @seq: seq_file handle 625 * @v: current iterator 626 * 627 * Return: None 628 */ qdf_mem_seq_stop(struct seq_file * seq,void * v)629 static void qdf_mem_seq_stop(struct seq_file *seq, void *v) { } 630 631 /** 632 * qdf_mem_seq_show() - print sequential callback 633 * @seq: seq_file handle 634 * @v: current iterator 635 * 636 * Return: 0 - success 637 */ qdf_mem_seq_show(struct seq_file * seq,void * v)638 static int qdf_mem_seq_show(struct seq_file *seq, void *v) 639 { 640 enum qdf_debug_domain domain_id = *(enum qdf_debug_domain *)v; 641 642 seq_printf(seq, "\n%s Memory Domain (Id %d)\n", 643 qdf_debug_domain_name(domain_id), domain_id); 644 qdf_mem_domain_print(qdf_mem_list_get(domain_id), 645 seq_printf_printer, 646 seq, 647 0, 648 qdf_mem_meta_table_print); 649 650 return 0; 651 } 652 653 /* sequential file operation table */ 654 static const struct seq_operations qdf_mem_seq_ops = { 655 .start = qdf_mem_seq_start, 656 .next = qdf_mem_seq_next, 657 .stop = qdf_mem_seq_stop, 658 .show = qdf_mem_seq_show, 659 }; 660 661 qdf_mem_debugfs_open(struct inode * inode,struct file * file)662 static int qdf_mem_debugfs_open(struct inode *inode, struct file *file) 663 { 664 return seq_open(file, &qdf_mem_seq_ops); 665 } 666 667 /** 668 * qdf_major_alloc_show() - print sequential callback 669 * @seq: seq_file handle 670 * @v: current iterator 671 * 672 * Return: 0 - success 673 */ qdf_major_alloc_show(struct seq_file * seq,void * v)674 static int qdf_major_alloc_show(struct seq_file *seq, void *v) 675 { 676 enum qdf_debug_domain domain_id = *(enum qdf_debug_domain *)v; 677 struct major_alloc_priv *priv; 678 qdf_list_t *list; 679 680 priv = (struct major_alloc_priv *)seq->private; 681 seq_printf(seq, "\n%s Memory Domain (Id %d)\n", 682 qdf_debug_domain_name(domain_id), domain_id); 683 684 switch (priv->type) { 685 case LIST_TYPE_MEM: 686 list = qdf_mem_list_get(domain_id); 687 break; 688 case LIST_TYPE_DMA: 689 list = qdf_mem_dma_list(domain_id); 690 break; 691 default: 692 list = NULL; 693 break; 694 } 695 696 if (list) 697 qdf_mem_domain_print(list, 698 seq_printf_printer, 699 seq, 700 priv->threshold, 701 qdf_print_major_alloc); 702 703 return 0; 704 } 705 706 /* sequential file operation table created to track major allocs */ 707 static const struct seq_operations qdf_major_allocs_seq_ops = { 708 .start = qdf_mem_seq_start, 709 .next = qdf_mem_seq_next, 710 .stop = qdf_mem_seq_stop, 711 .show = qdf_major_alloc_show, 712 }; 713 qdf_major_allocs_open(struct inode * inode,struct file * file)714 static int qdf_major_allocs_open(struct inode *inode, struct file *file) 715 { 716 void *private = inode->i_private; 717 struct seq_file *seq; 718 int rc; 719 720 rc = seq_open(file, &qdf_major_allocs_seq_ops); 721 if (rc == 0) { 722 seq = file->private_data; 723 seq->private = private; 724 } 725 return rc; 726 } 727 qdf_major_alloc_set_threshold(struct file * file,const char __user * user_buf,size_t count,loff_t * pos)728 static ssize_t qdf_major_alloc_set_threshold(struct file *file, 729 const char __user *user_buf, 730 size_t count, 731 loff_t *pos) 732 { 733 char buf[32]; 734 ssize_t buf_size; 735 uint32_t threshold; 736 struct seq_file *seq = file->private_data; 737 struct major_alloc_priv *priv = (struct major_alloc_priv *)seq->private; 738 739 buf_size = min(count, (sizeof(buf) - 1)); 740 if (buf_size <= 0) 741 return 0; 742 if (copy_from_user(buf, user_buf, buf_size)) 743 return -EFAULT; 744 buf[buf_size] = '\0'; 745 if (!kstrtou32(buf, 10, &threshold)) 746 priv->threshold = threshold; 747 return buf_size; 748 } 749 750 /** 751 * qdf_print_major_nbuf_allocs() - output agnostic nbuf print logic 752 * @threshold: the threshold value set by uset to list top allocations 753 * @print: the print adapter function 754 * @print_priv: the private data to be consumed by @print 755 * @mem_print: pointer to function which prints the memory allocation data 756 * 757 * Return: None 758 */ 759 static void qdf_print_major_nbuf_allocs(uint32_t threshold,qdf_abstract_print print,void * print_priv,void (* mem_print)(struct __qdf_mem_info *,qdf_abstract_print,void *,uint32_t))760 qdf_print_major_nbuf_allocs(uint32_t threshold, 761 qdf_abstract_print print, 762 void *print_priv, 763 void (*mem_print)(struct __qdf_mem_info *, 764 qdf_abstract_print, 765 void *, uint32_t)) 766 { 767 uint32_t nbuf_iter; 768 unsigned long irq_flag = 0; 769 QDF_NBUF_TRACK *p_node; 770 struct __qdf_mem_info table[QDF_MEM_STAT_TABLE_SIZE]; 771 struct qdf_mem_header meta; 772 bool is_full; 773 774 qdf_mem_zero(table, sizeof(table)); 775 qdf_mem_debug_print_header(print, print_priv, threshold); 776 777 if (is_initial_mem_debug_disabled) 778 return; 779 780 qdf_rl_info("major nbuf print with threshold %u", threshold); 781 782 for (nbuf_iter = 0; nbuf_iter < QDF_NET_BUF_TRACK_MAX_SIZE; 783 nbuf_iter++) { 784 qdf_nbuf_acquire_track_lock(nbuf_iter, irq_flag); 785 p_node = qdf_nbuf_get_track_tbl(nbuf_iter); 786 while (p_node) { 787 meta.line = p_node->line_num; 788 meta.size = p_node->size; 789 meta.caller = NULL; 790 meta.time = p_node->time; 791 qdf_str_lcopy(meta.func, p_node->func_name, 792 QDF_MEM_FUNC_NAME_SIZE); 793 794 is_full = qdf_mem_meta_table_insert(table, &meta); 795 796 if (is_full) { 797 (*mem_print)(table, print, 798 print_priv, threshold); 799 qdf_mem_zero(table, sizeof(table)); 800 } 801 802 p_node = p_node->p_next; 803 } 804 qdf_nbuf_release_track_lock(nbuf_iter, irq_flag); 805 } 806 807 (*mem_print)(table, print, print_priv, threshold); 808 809 qdf_rl_info("major nbuf print end"); 810 } 811 812 /** 813 * qdf_major_nbuf_alloc_show() - print sequential callback 814 * @seq: seq_file handle 815 * @v: current iterator 816 * 817 * Return: 0 - success 818 */ qdf_major_nbuf_alloc_show(struct seq_file * seq,void * v)819 static int qdf_major_nbuf_alloc_show(struct seq_file *seq, void *v) 820 { 821 struct major_alloc_priv *priv = (struct major_alloc_priv *)seq->private; 822 823 if (!priv) { 824 qdf_err("priv is null"); 825 return -EINVAL; 826 } 827 828 qdf_print_major_nbuf_allocs(priv->threshold, 829 seq_printf_printer, 830 seq, 831 qdf_print_major_alloc); 832 833 return 0; 834 } 835 836 /** 837 * qdf_nbuf_seq_start() - sequential callback to start 838 * @seq: seq_file handle 839 * @pos: The start position of the sequence 840 * 841 * Return: iterator pointer, or NULL if iteration is complete 842 */ qdf_nbuf_seq_start(struct seq_file * seq,loff_t * pos)843 static void *qdf_nbuf_seq_start(struct seq_file *seq, loff_t *pos) 844 { 845 enum qdf_debug_domain domain = *pos; 846 847 if (domain > QDF_DEBUG_NBUF_DOMAIN) 848 return NULL; 849 850 return pos; 851 } 852 853 /** 854 * qdf_nbuf_seq_next() - next sequential callback 855 * @seq: seq_file handle 856 * @v: the current iterator 857 * @pos: the current position 858 * 859 * Get the next node and release previous node. 860 * 861 * Return: iterator pointer, or NULL if iteration is complete 862 */ qdf_nbuf_seq_next(struct seq_file * seq,void * v,loff_t * pos)863 static void *qdf_nbuf_seq_next(struct seq_file *seq, void *v, loff_t *pos) 864 { 865 ++*pos; 866 867 return qdf_nbuf_seq_start(seq, pos); 868 } 869 870 /** 871 * qdf_nbuf_seq_stop() - stop sequential callback 872 * @seq: seq_file handle 873 * @v: current iterator 874 * 875 * Return: None 876 */ qdf_nbuf_seq_stop(struct seq_file * seq,void * v)877 static void qdf_nbuf_seq_stop(struct seq_file *seq, void *v) { } 878 879 /* sequential file operation table created to track major skb allocs */ 880 static const struct seq_operations qdf_major_nbuf_allocs_seq_ops = { 881 .start = qdf_nbuf_seq_start, 882 .next = qdf_nbuf_seq_next, 883 .stop = qdf_nbuf_seq_stop, 884 .show = qdf_major_nbuf_alloc_show, 885 }; 886 qdf_major_nbuf_allocs_open(struct inode * inode,struct file * file)887 static int qdf_major_nbuf_allocs_open(struct inode *inode, struct file *file) 888 { 889 void *private = inode->i_private; 890 struct seq_file *seq; 891 int rc; 892 893 rc = seq_open(file, &qdf_major_nbuf_allocs_seq_ops); 894 if (rc == 0) { 895 seq = file->private_data; 896 seq->private = private; 897 } 898 return rc; 899 } 900 qdf_major_nbuf_alloc_set_threshold(struct file * file,const char __user * user_buf,size_t count,loff_t * pos)901 static ssize_t qdf_major_nbuf_alloc_set_threshold(struct file *file, 902 const char __user *user_buf, 903 size_t count, 904 loff_t *pos) 905 { 906 char buf[32]; 907 ssize_t buf_size; 908 uint32_t threshold; 909 struct seq_file *seq = file->private_data; 910 struct major_alloc_priv *priv = (struct major_alloc_priv *)seq->private; 911 912 buf_size = min(count, (sizeof(buf) - 1)); 913 if (buf_size <= 0) 914 return 0; 915 if (copy_from_user(buf, user_buf, buf_size)) 916 return -EFAULT; 917 buf[buf_size] = '\0'; 918 if (!kstrtou32(buf, 10, &threshold)) 919 priv->threshold = threshold; 920 return buf_size; 921 } 922 923 /* file operation table for listing major allocs */ 924 static const struct file_operations fops_qdf_major_allocs = { 925 .owner = THIS_MODULE, 926 .open = qdf_major_allocs_open, 927 .read = seq_read, 928 .llseek = seq_lseek, 929 .release = seq_release, 930 .write = qdf_major_alloc_set_threshold, 931 }; 932 933 /* debugfs file operation table */ 934 static const struct file_operations fops_qdf_mem_debugfs = { 935 .owner = THIS_MODULE, 936 .open = qdf_mem_debugfs_open, 937 .read = seq_read, 938 .llseek = seq_lseek, 939 .release = seq_release, 940 }; 941 942 /* file operation table for listing major allocs */ 943 static const struct file_operations fops_qdf_nbuf_major_allocs = { 944 .owner = THIS_MODULE, 945 .open = qdf_major_nbuf_allocs_open, 946 .read = seq_read, 947 .llseek = seq_lseek, 948 .release = seq_release, 949 .write = qdf_major_nbuf_alloc_set_threshold, 950 }; 951 952 static struct major_alloc_priv mem_priv = { 953 /* List type set to mem */ 954 LIST_TYPE_MEM, 955 /* initial threshold to list APIs which allocates mem >= 50 times */ 956 50 957 }; 958 959 static struct major_alloc_priv dma_priv = { 960 /* List type set to DMA */ 961 LIST_TYPE_DMA, 962 /* initial threshold to list APIs which allocates dma >= 50 times */ 963 50 964 }; 965 966 static struct major_alloc_priv nbuf_priv = { 967 /* List type set to NBUF */ 968 LIST_TYPE_NBUF, 969 /* initial threshold to list APIs which allocates nbuf >= 50 times */ 970 50 971 }; 972 qdf_mem_debug_debugfs_init(void)973 static QDF_STATUS qdf_mem_debug_debugfs_init(void) 974 { 975 if (is_initial_mem_debug_disabled) 976 return QDF_STATUS_SUCCESS; 977 978 if (!qdf_mem_debugfs_root) 979 return QDF_STATUS_E_FAILURE; 980 981 debugfs_create_file("list", 982 S_IRUSR, 983 qdf_mem_debugfs_root, 984 NULL, 985 &fops_qdf_mem_debugfs); 986 987 debugfs_create_file("major_mem_allocs", 988 0600, 989 qdf_mem_debugfs_root, 990 &mem_priv, 991 &fops_qdf_major_allocs); 992 993 debugfs_create_file("major_dma_allocs", 994 0600, 995 qdf_mem_debugfs_root, 996 &dma_priv, 997 &fops_qdf_major_allocs); 998 999 debugfs_create_file("major_nbuf_allocs", 1000 0600, 1001 qdf_mem_debugfs_root, 1002 &nbuf_priv, 1003 &fops_qdf_nbuf_major_allocs); 1004 1005 return QDF_STATUS_SUCCESS; 1006 } 1007 qdf_mem_debug_debugfs_exit(void)1008 static QDF_STATUS qdf_mem_debug_debugfs_exit(void) 1009 { 1010 return QDF_STATUS_SUCCESS; 1011 } 1012 1013 #else /* MEMORY_DEBUG */ 1014 qdf_mem_debug_debugfs_init(void)1015 static QDF_STATUS qdf_mem_debug_debugfs_init(void) 1016 { 1017 return QDF_STATUS_E_NOSUPPORT; 1018 } 1019 qdf_mem_debug_debugfs_exit(void)1020 static QDF_STATUS qdf_mem_debug_debugfs_exit(void) 1021 { 1022 return QDF_STATUS_E_NOSUPPORT; 1023 } 1024 1025 #endif /* MEMORY_DEBUG */ 1026 1027 qdf_mem_debugfs_exit(void)1028 static void qdf_mem_debugfs_exit(void) 1029 { 1030 debugfs_remove_recursive(qdf_mem_debugfs_root); 1031 qdf_mem_debugfs_root = NULL; 1032 } 1033 qdf_mem_debugfs_init(void)1034 static QDF_STATUS qdf_mem_debugfs_init(void) 1035 { 1036 struct dentry *qdf_debugfs_root = qdf_debugfs_get_root(); 1037 1038 if (!qdf_debugfs_root) 1039 return QDF_STATUS_E_FAILURE; 1040 1041 qdf_mem_debugfs_root = debugfs_create_dir("mem", qdf_debugfs_root); 1042 1043 if (!qdf_mem_debugfs_root) 1044 return QDF_STATUS_E_FAILURE; 1045 1046 1047 debugfs_create_atomic_t("kmalloc", 1048 S_IRUSR, 1049 qdf_mem_debugfs_root, 1050 &qdf_mem_stat.kmalloc); 1051 1052 debugfs_create_atomic_t("dma", 1053 S_IRUSR, 1054 qdf_mem_debugfs_root, 1055 &qdf_mem_stat.dma); 1056 1057 debugfs_create_atomic_t("skb", 1058 S_IRUSR, 1059 qdf_mem_debugfs_root, 1060 &qdf_mem_stat.skb); 1061 1062 return QDF_STATUS_SUCCESS; 1063 } 1064 1065 #else /* WLAN_DEBUGFS */ 1066 qdf_mem_debugfs_init(void)1067 static QDF_STATUS qdf_mem_debugfs_init(void) 1068 { 1069 return QDF_STATUS_E_NOSUPPORT; 1070 } qdf_mem_debugfs_exit(void)1071 static void qdf_mem_debugfs_exit(void) {} 1072 1073 qdf_mem_debug_debugfs_init(void)1074 static QDF_STATUS qdf_mem_debug_debugfs_init(void) 1075 { 1076 return QDF_STATUS_E_NOSUPPORT; 1077 } 1078 qdf_mem_debug_debugfs_exit(void)1079 static QDF_STATUS qdf_mem_debug_debugfs_exit(void) 1080 { 1081 return QDF_STATUS_E_NOSUPPORT; 1082 } 1083 1084 #endif /* WLAN_DEBUGFS */ 1085 qdf_mem_kmalloc_inc(qdf_size_t size)1086 void qdf_mem_kmalloc_inc(qdf_size_t size) 1087 { 1088 qdf_atomic_add(size, &qdf_mem_stat.kmalloc); 1089 } 1090 qdf_mem_dma_inc(qdf_size_t size)1091 static void qdf_mem_dma_inc(qdf_size_t size) 1092 { 1093 qdf_atomic_add(size, &qdf_mem_stat.dma); 1094 } 1095 1096 #ifdef CONFIG_WLAN_SYSFS_MEM_STATS qdf_mem_skb_inc(qdf_size_t size)1097 void qdf_mem_skb_inc(qdf_size_t size) 1098 { 1099 qdf_atomic_add(size, &qdf_mem_stat.skb); 1100 } 1101 qdf_mem_skb_dec(qdf_size_t size)1102 void qdf_mem_skb_dec(qdf_size_t size) 1103 { 1104 qdf_atomic_sub(size, &qdf_mem_stat.skb); 1105 } 1106 qdf_mem_skb_total_inc(qdf_size_t size)1107 void qdf_mem_skb_total_inc(qdf_size_t size) 1108 { 1109 int32_t skb_mem_max = 0; 1110 1111 qdf_atomic_add(size, &qdf_mem_stat.skb_total); 1112 skb_mem_max = qdf_atomic_read(&qdf_mem_stat.skb_total); 1113 if (qdf_mem_stat.skb_mem_max < skb_mem_max) 1114 qdf_mem_stat.skb_mem_max = skb_mem_max; 1115 } 1116 qdf_mem_skb_total_dec(qdf_size_t size)1117 void qdf_mem_skb_total_dec(qdf_size_t size) 1118 { 1119 qdf_atomic_sub(size, &qdf_mem_stat.skb_total); 1120 } 1121 qdf_mem_dp_tx_skb_inc(qdf_size_t size)1122 void qdf_mem_dp_tx_skb_inc(qdf_size_t size) 1123 { 1124 int32_t curr_dp_tx_skb_mem_max = 0; 1125 1126 qdf_atomic_add(size, &qdf_mem_stat.dp_tx_skb); 1127 curr_dp_tx_skb_mem_max = qdf_atomic_read(&qdf_mem_stat.dp_tx_skb); 1128 if (qdf_mem_stat.dp_tx_skb_mem_max < curr_dp_tx_skb_mem_max) 1129 qdf_mem_stat.dp_tx_skb_mem_max = curr_dp_tx_skb_mem_max; 1130 } 1131 qdf_mem_dp_tx_skb_dec(qdf_size_t size)1132 void qdf_mem_dp_tx_skb_dec(qdf_size_t size) 1133 { 1134 qdf_atomic_sub(size, &qdf_mem_stat.dp_tx_skb); 1135 } 1136 qdf_mem_dp_rx_skb_inc(qdf_size_t size)1137 void qdf_mem_dp_rx_skb_inc(qdf_size_t size) 1138 { 1139 int32_t curr_dp_rx_skb_mem_max = 0; 1140 1141 qdf_atomic_add(size, &qdf_mem_stat.dp_rx_skb); 1142 curr_dp_rx_skb_mem_max = qdf_atomic_read(&qdf_mem_stat.dp_rx_skb); 1143 if (qdf_mem_stat.dp_rx_skb_mem_max < curr_dp_rx_skb_mem_max) 1144 qdf_mem_stat.dp_rx_skb_mem_max = curr_dp_rx_skb_mem_max; 1145 } 1146 qdf_mem_dp_rx_skb_dec(qdf_size_t size)1147 void qdf_mem_dp_rx_skb_dec(qdf_size_t size) 1148 { 1149 qdf_atomic_sub(size, &qdf_mem_stat.dp_rx_skb); 1150 } 1151 qdf_mem_dp_tx_skb_cnt_inc(void)1152 void qdf_mem_dp_tx_skb_cnt_inc(void) 1153 { 1154 int32_t curr_dp_tx_skb_count_max = 0; 1155 1156 qdf_atomic_add(1, &qdf_mem_stat.dp_tx_skb_count); 1157 curr_dp_tx_skb_count_max = 1158 qdf_atomic_read(&qdf_mem_stat.dp_tx_skb_count); 1159 if (qdf_mem_stat.dp_tx_skb_count_max < curr_dp_tx_skb_count_max) 1160 qdf_mem_stat.dp_tx_skb_count_max = curr_dp_tx_skb_count_max; 1161 } 1162 qdf_mem_dp_tx_skb_cnt_dec(void)1163 void qdf_mem_dp_tx_skb_cnt_dec(void) 1164 { 1165 qdf_atomic_sub(1, &qdf_mem_stat.dp_tx_skb_count); 1166 } 1167 qdf_mem_dp_rx_skb_cnt_inc(void)1168 void qdf_mem_dp_rx_skb_cnt_inc(void) 1169 { 1170 int32_t curr_dp_rx_skb_count_max = 0; 1171 1172 qdf_atomic_add(1, &qdf_mem_stat.dp_rx_skb_count); 1173 curr_dp_rx_skb_count_max = 1174 qdf_atomic_read(&qdf_mem_stat.dp_rx_skb_count); 1175 if (qdf_mem_stat.dp_rx_skb_count_max < curr_dp_rx_skb_count_max) 1176 qdf_mem_stat.dp_rx_skb_count_max = curr_dp_rx_skb_count_max; 1177 } 1178 qdf_mem_dp_rx_skb_cnt_dec(void)1179 void qdf_mem_dp_rx_skb_cnt_dec(void) 1180 { 1181 qdf_atomic_sub(1, &qdf_mem_stat.dp_rx_skb_count); 1182 } 1183 #endif 1184 qdf_mem_kmalloc_dec(qdf_size_t size)1185 void qdf_mem_kmalloc_dec(qdf_size_t size) 1186 { 1187 qdf_atomic_sub(size, &qdf_mem_stat.kmalloc); 1188 } 1189 qdf_mem_dma_dec(qdf_size_t size)1190 static inline void qdf_mem_dma_dec(qdf_size_t size) 1191 { 1192 qdf_atomic_sub(size, &qdf_mem_stat.dma); 1193 } 1194 __qdf_mempool_init(qdf_device_t osdev,__qdf_mempool_t * pool_addr,int elem_cnt,size_t elem_size,u_int32_t flags)1195 int __qdf_mempool_init(qdf_device_t osdev, __qdf_mempool_t *pool_addr, 1196 int elem_cnt, size_t elem_size, u_int32_t flags) 1197 { 1198 __qdf_mempool_ctxt_t *new_pool = NULL; 1199 u_int32_t align = L1_CACHE_BYTES; 1200 unsigned long aligned_pool_mem; 1201 int pool_id; 1202 int i; 1203 1204 if (prealloc_disabled) { 1205 /* TBD: We can maintain a list of pools in qdf_device_t 1206 * to help debugging 1207 * when pre-allocation is not enabled 1208 */ 1209 new_pool = (__qdf_mempool_ctxt_t *) 1210 kmalloc(sizeof(__qdf_mempool_ctxt_t), GFP_KERNEL); 1211 if (!new_pool) 1212 return QDF_STATUS_E_NOMEM; 1213 1214 memset(new_pool, 0, sizeof(*new_pool)); 1215 /* TBD: define flags for zeroing buffers etc */ 1216 new_pool->flags = flags; 1217 new_pool->elem_size = elem_size; 1218 new_pool->max_elem = elem_cnt; 1219 *pool_addr = new_pool; 1220 return 0; 1221 } 1222 1223 for (pool_id = 0; pool_id < MAX_MEM_POOLS; pool_id++) { 1224 if (!osdev->mem_pool[pool_id]) 1225 break; 1226 } 1227 1228 if (pool_id == MAX_MEM_POOLS) 1229 return -ENOMEM; 1230 1231 new_pool = osdev->mem_pool[pool_id] = (__qdf_mempool_ctxt_t *) 1232 kmalloc(sizeof(__qdf_mempool_ctxt_t), GFP_KERNEL); 1233 if (!new_pool) 1234 return -ENOMEM; 1235 1236 memset(new_pool, 0, sizeof(*new_pool)); 1237 /* TBD: define flags for zeroing buffers etc */ 1238 new_pool->flags = flags; 1239 new_pool->pool_id = pool_id; 1240 1241 /* Round up the element size to cacheline */ 1242 new_pool->elem_size = roundup(elem_size, L1_CACHE_BYTES); 1243 new_pool->mem_size = elem_cnt * new_pool->elem_size + 1244 ((align)?(align - 1):0); 1245 1246 new_pool->pool_mem = kzalloc(new_pool->mem_size, GFP_KERNEL); 1247 if (!new_pool->pool_mem) { 1248 /* TBD: Check if we need get_free_pages above */ 1249 kfree(new_pool); 1250 osdev->mem_pool[pool_id] = NULL; 1251 return -ENOMEM; 1252 } 1253 1254 spin_lock_init(&new_pool->lock); 1255 1256 /* Initialize free list */ 1257 aligned_pool_mem = (unsigned long)(new_pool->pool_mem) + 1258 ((align) ? (unsigned long)(new_pool->pool_mem)%align:0); 1259 STAILQ_INIT(&new_pool->free_list); 1260 1261 for (i = 0; i < elem_cnt; i++) 1262 STAILQ_INSERT_TAIL(&(new_pool->free_list), 1263 (mempool_elem_t *)(aligned_pool_mem + 1264 (new_pool->elem_size * i)), mempool_entry); 1265 1266 1267 new_pool->free_cnt = elem_cnt; 1268 *pool_addr = new_pool; 1269 return 0; 1270 } 1271 qdf_export_symbol(__qdf_mempool_init); 1272 __qdf_mempool_destroy(qdf_device_t osdev,__qdf_mempool_t pool)1273 void __qdf_mempool_destroy(qdf_device_t osdev, __qdf_mempool_t pool) 1274 { 1275 int pool_id = 0; 1276 1277 if (!pool) 1278 return; 1279 1280 if (prealloc_disabled) { 1281 kfree(pool); 1282 return; 1283 } 1284 1285 pool_id = pool->pool_id; 1286 1287 /* TBD: Check if free count matches elem_cnt if debug is enabled */ 1288 kfree(pool->pool_mem); 1289 kfree(pool); 1290 osdev->mem_pool[pool_id] = NULL; 1291 } 1292 qdf_export_symbol(__qdf_mempool_destroy); 1293 __qdf_mempool_alloc(qdf_device_t osdev,__qdf_mempool_t pool)1294 void *__qdf_mempool_alloc(qdf_device_t osdev, __qdf_mempool_t pool) 1295 { 1296 void *buf = NULL; 1297 1298 if (!pool) 1299 return NULL; 1300 1301 if (prealloc_disabled) 1302 return qdf_mem_malloc(pool->elem_size); 1303 1304 spin_lock_bh(&pool->lock); 1305 1306 buf = STAILQ_FIRST(&pool->free_list); 1307 if (buf) { 1308 STAILQ_REMOVE_HEAD(&pool->free_list, mempool_entry); 1309 pool->free_cnt--; 1310 } 1311 1312 /* TBD: Update free count if debug is enabled */ 1313 spin_unlock_bh(&pool->lock); 1314 1315 return buf; 1316 } 1317 qdf_export_symbol(__qdf_mempool_alloc); 1318 __qdf_mempool_free(qdf_device_t osdev,__qdf_mempool_t pool,void * buf)1319 void __qdf_mempool_free(qdf_device_t osdev, __qdf_mempool_t pool, void *buf) 1320 { 1321 if (!pool) 1322 return; 1323 1324 1325 if (prealloc_disabled) 1326 return qdf_mem_free(buf); 1327 1328 spin_lock_bh(&pool->lock); 1329 pool->free_cnt++; 1330 1331 STAILQ_INSERT_TAIL 1332 (&pool->free_list, (mempool_elem_t *)buf, mempool_entry); 1333 spin_unlock_bh(&pool->lock); 1334 } 1335 qdf_export_symbol(__qdf_mempool_free); 1336 1337 #ifdef CNSS_MEM_PRE_ALLOC qdf_might_be_prealloc(void * ptr)1338 static bool qdf_might_be_prealloc(void *ptr) 1339 { 1340 if (ksize(ptr) > WCNSS_PRE_ALLOC_GET_THRESHOLD) 1341 return true; 1342 else 1343 return false; 1344 } 1345 1346 /** 1347 * qdf_mem_prealloc_get() - conditionally pre-allocate memory 1348 * @size: the number of bytes to allocate 1349 * 1350 * If size if greater than WCNSS_PRE_ALLOC_GET_THRESHOLD, this function returns 1351 * a chunk of pre-allocated memory. If size if less than or equal to 1352 * WCNSS_PRE_ALLOC_GET_THRESHOLD, or an error occurs, NULL is returned instead. 1353 * 1354 * Return: NULL on failure, non-NULL on success 1355 */ qdf_mem_prealloc_get(size_t size)1356 static void *qdf_mem_prealloc_get(size_t size) 1357 { 1358 void *ptr; 1359 1360 if (size <= WCNSS_PRE_ALLOC_GET_THRESHOLD) 1361 return NULL; 1362 1363 ptr = wcnss_prealloc_get(size); 1364 if (!ptr) 1365 return NULL; 1366 1367 memset(ptr, 0, size); 1368 1369 return ptr; 1370 } 1371 qdf_mem_prealloc_put(void * ptr)1372 static inline bool qdf_mem_prealloc_put(void *ptr) 1373 { 1374 return wcnss_prealloc_put(ptr); 1375 } 1376 #else qdf_might_be_prealloc(void * ptr)1377 static bool qdf_might_be_prealloc(void *ptr) 1378 { 1379 return false; 1380 } 1381 qdf_mem_prealloc_get(size_t size)1382 static inline void *qdf_mem_prealloc_get(size_t size) 1383 { 1384 return NULL; 1385 } 1386 qdf_mem_prealloc_put(void * ptr)1387 static inline bool qdf_mem_prealloc_put(void *ptr) 1388 { 1389 return false; 1390 } 1391 #endif /* CNSS_MEM_PRE_ALLOC */ 1392 1393 /* External Function implementation */ 1394 #ifdef MEMORY_DEBUG 1395 #ifdef DISABLE_MEM_DBG_LOAD_CONFIG qdf_mem_debug_config_get(void)1396 bool qdf_mem_debug_config_get(void) 1397 { 1398 /* Return false if DISABLE_LOAD_MEM_DBG_CONFIG flag is enabled */ 1399 return false; 1400 } 1401 #else qdf_mem_debug_config_get(void)1402 bool qdf_mem_debug_config_get(void) 1403 { 1404 return mem_debug_disabled; 1405 } 1406 #endif /* DISABLE_MEM_DBG_LOAD_CONFIG */ 1407 1408 #ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI qdf_mem_debug_disabled_config_set(const char * str_value)1409 QDF_STATUS qdf_mem_debug_disabled_config_set(const char *str_value) 1410 { 1411 QDF_STATUS status; 1412 1413 status = qdf_bool_parse(str_value, &mem_debug_disabled); 1414 return status; 1415 } 1416 #endif 1417 1418 /** 1419 * qdf_mem_debug_init() - initialize qdf memory debug functionality 1420 * 1421 * Return: none 1422 */ qdf_mem_debug_init(void)1423 static void qdf_mem_debug_init(void) 1424 { 1425 int i; 1426 1427 is_initial_mem_debug_disabled = qdf_mem_debug_config_get(); 1428 1429 if (is_initial_mem_debug_disabled) 1430 return; 1431 1432 /* Initializing the list with maximum size of 60000 */ 1433 for (i = 0; i < QDF_DEBUG_DOMAIN_COUNT; ++i) 1434 qdf_list_create(&qdf_mem_domains[i], 60000); 1435 qdf_spinlock_create(&qdf_mem_list_lock); 1436 1437 /* dma */ 1438 for (i = 0; i < QDF_DEBUG_DOMAIN_COUNT; ++i) 1439 qdf_list_create(&qdf_mem_dma_domains[i], 0); 1440 qdf_spinlock_create(&qdf_mem_dma_list_lock); 1441 } 1442 1443 static uint32_t qdf_mem_domain_check_for_leaks(enum qdf_debug_domain domain,qdf_list_t * mem_list)1444 qdf_mem_domain_check_for_leaks(enum qdf_debug_domain domain, 1445 qdf_list_t *mem_list) 1446 { 1447 if (is_initial_mem_debug_disabled) 1448 return 0; 1449 1450 if (qdf_list_empty(mem_list)) 1451 return 0; 1452 1453 qdf_err("Memory leaks detected in %s domain!", 1454 qdf_debug_domain_name(domain)); 1455 qdf_mem_domain_print(mem_list, 1456 qdf_err_printer, 1457 NULL, 1458 0, 1459 qdf_mem_meta_table_print); 1460 1461 return mem_list->count; 1462 } 1463 qdf_mem_domain_set_check_for_leaks(qdf_list_t * domains)1464 static void qdf_mem_domain_set_check_for_leaks(qdf_list_t *domains) 1465 { 1466 uint32_t leak_count = 0; 1467 int i; 1468 1469 if (is_initial_mem_debug_disabled) 1470 return; 1471 1472 /* detect and print leaks */ 1473 for (i = 0; i < QDF_DEBUG_DOMAIN_COUNT; ++i) 1474 leak_count += qdf_mem_domain_check_for_leaks(i, domains + i); 1475 1476 if (leak_count) 1477 QDF_MEMDEBUG_PANIC("%u fatal memory leaks detected!", 1478 leak_count); 1479 } 1480 1481 /** 1482 * qdf_mem_debug_exit() - exit qdf memory debug functionality 1483 * 1484 * Return: none 1485 */ qdf_mem_debug_exit(void)1486 static void qdf_mem_debug_exit(void) 1487 { 1488 int i; 1489 1490 if (is_initial_mem_debug_disabled) 1491 return; 1492 1493 /* mem */ 1494 qdf_mem_domain_set_check_for_leaks(qdf_mem_domains); 1495 for (i = 0; i < QDF_DEBUG_DOMAIN_COUNT; ++i) 1496 qdf_list_destroy(qdf_mem_list_get(i)); 1497 1498 qdf_spinlock_destroy(&qdf_mem_list_lock); 1499 1500 /* dma */ 1501 qdf_mem_domain_set_check_for_leaks(qdf_mem_dma_domains); 1502 for (i = 0; i < QDF_DEBUG_DOMAIN_COUNT; ++i) 1503 qdf_list_destroy(&qdf_mem_dma_domains[i]); 1504 qdf_spinlock_destroy(&qdf_mem_dma_list_lock); 1505 } 1506 qdf_mem_malloc_debug(size_t size,const char * func,uint32_t line,void * caller,uint32_t flag)1507 void *qdf_mem_malloc_debug(size_t size, const char *func, uint32_t line, 1508 void *caller, uint32_t flag) 1509 { 1510 QDF_STATUS status; 1511 enum qdf_debug_domain current_domain = qdf_debug_domain_get(); 1512 qdf_list_t *mem_list = qdf_mem_list_get(current_domain); 1513 struct qdf_mem_header *header; 1514 void *ptr; 1515 unsigned long start, duration; 1516 1517 if (is_initial_mem_debug_disabled) 1518 return __qdf_mem_malloc(size, func, line); 1519 1520 if (!size || size > QDF_MEM_MAX_MALLOC) { 1521 qdf_err("Cannot malloc %zu bytes @ %s:%d", size, func, line); 1522 return NULL; 1523 } 1524 1525 ptr = qdf_mem_prealloc_get(size); 1526 if (ptr) 1527 return ptr; 1528 1529 if (!flag) 1530 flag = qdf_mem_malloc_flags(); 1531 1532 start = qdf_mc_timer_get_system_time(); 1533 header = kzalloc(size + QDF_MEM_DEBUG_SIZE, flag); 1534 duration = qdf_mc_timer_get_system_time() - start; 1535 1536 if (duration > QDF_MEM_WARN_THRESHOLD) 1537 qdf_warn("Malloc slept; %lums, %zuB @ %s:%d", 1538 duration, size, func, line); 1539 1540 if (!header) { 1541 qdf_warn("Failed to malloc %zuB @ %s:%d", size, func, line); 1542 return NULL; 1543 } 1544 1545 qdf_mem_header_init(header, size, func, line, caller); 1546 qdf_mem_trailer_init(header); 1547 ptr = qdf_mem_get_ptr(header); 1548 1549 qdf_spin_lock_irqsave(&qdf_mem_list_lock); 1550 status = qdf_list_insert_front(mem_list, &header->node); 1551 qdf_spin_unlock_irqrestore(&qdf_mem_list_lock); 1552 if (QDF_IS_STATUS_ERROR(status)) 1553 qdf_err("Failed to insert memory header; status %d", status); 1554 1555 qdf_mem_kmalloc_inc(ksize(header)); 1556 1557 return ptr; 1558 } 1559 qdf_export_symbol(qdf_mem_malloc_debug); 1560 qdf_mem_malloc_atomic_debug(size_t size,const char * func,uint32_t line,void * caller)1561 void *qdf_mem_malloc_atomic_debug(size_t size, const char *func, 1562 uint32_t line, void *caller) 1563 { 1564 QDF_STATUS status; 1565 enum qdf_debug_domain current_domain = qdf_debug_domain_get(); 1566 qdf_list_t *mem_list = qdf_mem_list_get(current_domain); 1567 struct qdf_mem_header *header; 1568 void *ptr; 1569 unsigned long start, duration; 1570 1571 if (is_initial_mem_debug_disabled) 1572 return qdf_mem_malloc_atomic_debug_fl(size, func, line); 1573 1574 if (!size || size > QDF_MEM_MAX_MALLOC) { 1575 qdf_err("Cannot malloc %zu bytes @ %s:%d", size, func, line); 1576 return NULL; 1577 } 1578 1579 ptr = qdf_mem_prealloc_get(size); 1580 if (ptr) 1581 return ptr; 1582 1583 start = qdf_mc_timer_get_system_time(); 1584 header = kzalloc(size + QDF_MEM_DEBUG_SIZE, GFP_ATOMIC); 1585 duration = qdf_mc_timer_get_system_time() - start; 1586 1587 if (duration > QDF_MEM_WARN_THRESHOLD) 1588 qdf_warn("Malloc slept; %lums, %zuB @ %s:%d", 1589 duration, size, func, line); 1590 1591 if (!header) { 1592 qdf_warn("Failed to malloc %zuB @ %s:%d", size, func, line); 1593 return NULL; 1594 } 1595 1596 qdf_mem_header_init(header, size, func, line, caller); 1597 qdf_mem_trailer_init(header); 1598 ptr = qdf_mem_get_ptr(header); 1599 1600 qdf_spin_lock_irqsave(&qdf_mem_list_lock); 1601 status = qdf_list_insert_front(mem_list, &header->node); 1602 qdf_spin_unlock_irqrestore(&qdf_mem_list_lock); 1603 if (QDF_IS_STATUS_ERROR(status)) 1604 qdf_err("Failed to insert memory header; status %d", status); 1605 1606 qdf_mem_kmalloc_inc(ksize(header)); 1607 1608 return ptr; 1609 } 1610 1611 qdf_export_symbol(qdf_mem_malloc_atomic_debug); 1612 qdf_mem_malloc_atomic_debug_fl(size_t size,const char * func,uint32_t line)1613 void *qdf_mem_malloc_atomic_debug_fl(size_t size, const char *func, 1614 uint32_t line) 1615 { 1616 void *ptr; 1617 1618 if (!size || size > QDF_MEM_MAX_MALLOC) { 1619 qdf_nofl_err("Cannot malloc %zu bytes @ %s:%d", size, func, 1620 line); 1621 return NULL; 1622 } 1623 1624 ptr = qdf_mem_prealloc_get(size); 1625 if (ptr) 1626 return ptr; 1627 1628 ptr = kzalloc(size, GFP_ATOMIC); 1629 if (!ptr) { 1630 qdf_nofl_warn("Failed to malloc %zuB @ %s:%d", 1631 size, func, line); 1632 return NULL; 1633 } 1634 1635 qdf_mem_kmalloc_inc(ksize(ptr)); 1636 1637 return ptr; 1638 } 1639 1640 qdf_export_symbol(qdf_mem_malloc_atomic_debug_fl); 1641 qdf_mem_free_debug(void * ptr,const char * func,uint32_t line)1642 void qdf_mem_free_debug(void *ptr, const char *func, uint32_t line) 1643 { 1644 enum qdf_debug_domain current_domain = qdf_debug_domain_get(); 1645 struct qdf_mem_header *header; 1646 enum qdf_mem_validation_bitmap error_bitmap; 1647 1648 if (is_initial_mem_debug_disabled) { 1649 __qdf_mem_free(ptr); 1650 return; 1651 } 1652 1653 /* freeing a null pointer is valid */ 1654 if (qdf_unlikely(!ptr)) 1655 return; 1656 1657 if (qdf_mem_prealloc_put(ptr)) 1658 return; 1659 1660 if (qdf_unlikely((qdf_size_t)ptr <= sizeof(*header))) 1661 QDF_MEMDEBUG_PANIC("Failed to free invalid memory location %pK", 1662 ptr); 1663 1664 qdf_talloc_assert_no_children_fl(ptr, func, line); 1665 1666 qdf_spin_lock_irqsave(&qdf_mem_list_lock); 1667 header = qdf_mem_get_header(ptr); 1668 error_bitmap = qdf_mem_header_validate(header, current_domain); 1669 error_bitmap |= qdf_mem_trailer_validate(header); 1670 1671 if (!error_bitmap) { 1672 header->freed = true; 1673 qdf_list_remove_node(qdf_mem_list_get(header->domain), 1674 &header->node); 1675 } 1676 qdf_spin_unlock_irqrestore(&qdf_mem_list_lock); 1677 1678 qdf_mem_header_assert_valid(header, current_domain, error_bitmap, 1679 func, line); 1680 1681 qdf_mem_kmalloc_dec(ksize(header)); 1682 kfree(header); 1683 } 1684 qdf_export_symbol(qdf_mem_free_debug); 1685 qdf_mem_check_for_leaks(void)1686 void qdf_mem_check_for_leaks(void) 1687 { 1688 enum qdf_debug_domain current_domain = qdf_debug_domain_get(); 1689 qdf_list_t *mem_list = qdf_mem_list_get(current_domain); 1690 qdf_list_t *dma_list = qdf_mem_dma_list(current_domain); 1691 uint32_t leaks_count = 0; 1692 1693 if (is_initial_mem_debug_disabled) 1694 return; 1695 1696 leaks_count += qdf_mem_domain_check_for_leaks(current_domain, mem_list); 1697 leaks_count += qdf_mem_domain_check_for_leaks(current_domain, dma_list); 1698 1699 if (leaks_count) 1700 QDF_MEMDEBUG_PANIC("%u fatal memory leaks detected!", 1701 leaks_count); 1702 } 1703 qdf_mem_multi_pages_alloc_debug(qdf_device_t osdev,struct qdf_mem_multi_page_t * pages,size_t element_size,uint32_t element_num,qdf_dma_context_t memctxt,bool cacheable,const char * func,uint32_t line,void * caller)1704 void qdf_mem_multi_pages_alloc_debug(qdf_device_t osdev, 1705 struct qdf_mem_multi_page_t *pages, 1706 size_t element_size, uint32_t element_num, 1707 qdf_dma_context_t memctxt, bool cacheable, 1708 const char *func, uint32_t line, 1709 void *caller) 1710 { 1711 uint16_t page_idx; 1712 struct qdf_mem_dma_page_t *dma_pages; 1713 void **cacheable_pages = NULL; 1714 uint16_t i; 1715 1716 if (!pages->page_size) 1717 pages->page_size = qdf_page_size; 1718 1719 pages->num_element_per_page = pages->page_size / element_size; 1720 if (!pages->num_element_per_page) { 1721 qdf_print("Invalid page %d or element size %d", 1722 (int)pages->page_size, (int)element_size); 1723 goto out_fail; 1724 } 1725 1726 pages->num_pages = element_num / pages->num_element_per_page; 1727 if (element_num % pages->num_element_per_page) 1728 pages->num_pages++; 1729 1730 if (cacheable) { 1731 /* Pages information storage */ 1732 pages->cacheable_pages = qdf_mem_malloc_debug( 1733 pages->num_pages * sizeof(pages->cacheable_pages), 1734 func, line, caller, 0); 1735 if (!pages->cacheable_pages) 1736 goto out_fail; 1737 1738 cacheable_pages = pages->cacheable_pages; 1739 for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { 1740 cacheable_pages[page_idx] = qdf_mem_malloc_debug( 1741 pages->page_size, func, line, caller, 0); 1742 if (!cacheable_pages[page_idx]) 1743 goto page_alloc_fail; 1744 } 1745 pages->dma_pages = NULL; 1746 } else { 1747 pages->dma_pages = qdf_mem_malloc_debug( 1748 pages->num_pages * sizeof(struct qdf_mem_dma_page_t), 1749 func, line, caller, 0); 1750 if (!pages->dma_pages) 1751 goto out_fail; 1752 1753 dma_pages = pages->dma_pages; 1754 for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { 1755 dma_pages->page_v_addr_start = 1756 qdf_mem_alloc_consistent_debug( 1757 osdev, osdev->dev, pages->page_size, 1758 &dma_pages->page_p_addr, 1759 func, line, caller); 1760 if (!dma_pages->page_v_addr_start) { 1761 qdf_print("dmaable page alloc fail pi %d", 1762 page_idx); 1763 goto page_alloc_fail; 1764 } 1765 dma_pages->page_v_addr_end = 1766 dma_pages->page_v_addr_start + pages->page_size; 1767 dma_pages++; 1768 } 1769 pages->cacheable_pages = NULL; 1770 } 1771 return; 1772 1773 page_alloc_fail: 1774 if (cacheable) { 1775 for (i = 0; i < page_idx; i++) 1776 qdf_mem_free_debug(pages->cacheable_pages[i], 1777 func, line); 1778 qdf_mem_free_debug(pages->cacheable_pages, func, line); 1779 } else { 1780 dma_pages = pages->dma_pages; 1781 for (i = 0; i < page_idx; i++) { 1782 qdf_mem_free_consistent_debug( 1783 osdev, osdev->dev, 1784 pages->page_size, dma_pages->page_v_addr_start, 1785 dma_pages->page_p_addr, memctxt, func, line); 1786 dma_pages++; 1787 } 1788 qdf_mem_free_debug(pages->dma_pages, func, line); 1789 } 1790 1791 out_fail: 1792 pages->cacheable_pages = NULL; 1793 pages->dma_pages = NULL; 1794 pages->num_pages = 0; 1795 } 1796 1797 qdf_export_symbol(qdf_mem_multi_pages_alloc_debug); 1798 qdf_mem_multi_pages_free_debug(qdf_device_t osdev,struct qdf_mem_multi_page_t * pages,qdf_dma_context_t memctxt,bool cacheable,const char * func,uint32_t line)1799 void qdf_mem_multi_pages_free_debug(qdf_device_t osdev, 1800 struct qdf_mem_multi_page_t *pages, 1801 qdf_dma_context_t memctxt, bool cacheable, 1802 const char *func, uint32_t line) 1803 { 1804 unsigned int page_idx; 1805 struct qdf_mem_dma_page_t *dma_pages; 1806 1807 if (!pages->page_size) 1808 pages->page_size = qdf_page_size; 1809 1810 if (cacheable) { 1811 for (page_idx = 0; page_idx < pages->num_pages; page_idx++) 1812 qdf_mem_free_debug(pages->cacheable_pages[page_idx], 1813 func, line); 1814 qdf_mem_free_debug(pages->cacheable_pages, func, line); 1815 } else { 1816 dma_pages = pages->dma_pages; 1817 for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { 1818 qdf_mem_free_consistent_debug( 1819 osdev, osdev->dev, pages->page_size, 1820 dma_pages->page_v_addr_start, 1821 dma_pages->page_p_addr, memctxt, func, line); 1822 dma_pages++; 1823 } 1824 qdf_mem_free_debug(pages->dma_pages, func, line); 1825 } 1826 1827 pages->cacheable_pages = NULL; 1828 pages->dma_pages = NULL; 1829 pages->num_pages = 0; 1830 } 1831 1832 qdf_export_symbol(qdf_mem_multi_pages_free_debug); 1833 1834 #else qdf_mem_debug_init(void)1835 static void qdf_mem_debug_init(void) {} 1836 qdf_mem_debug_exit(void)1837 static void qdf_mem_debug_exit(void) {} 1838 qdf_mem_malloc_atomic_fl(size_t size,const char * func,uint32_t line)1839 void *qdf_mem_malloc_atomic_fl(size_t size, const char *func, uint32_t line) 1840 { 1841 void *ptr; 1842 1843 if (!size || size > QDF_MEM_MAX_MALLOC) { 1844 qdf_nofl_err("Cannot malloc %zu bytes @ %s:%d", size, func, 1845 line); 1846 return NULL; 1847 } 1848 1849 ptr = qdf_mem_prealloc_get(size); 1850 if (ptr) 1851 return ptr; 1852 1853 ptr = kzalloc(size, GFP_ATOMIC); 1854 if (!ptr) { 1855 qdf_nofl_warn("Failed to malloc %zuB @ %s:%d", 1856 size, func, line); 1857 return NULL; 1858 } 1859 1860 qdf_mem_kmalloc_inc(ksize(ptr)); 1861 1862 return ptr; 1863 } 1864 qdf_export_symbol(qdf_mem_malloc_atomic_fl); 1865 1866 #ifndef ALLOC_CONTIGUOUS_MULTI_PAGE qdf_mem_multi_pages_alloc(qdf_device_t osdev,struct qdf_mem_multi_page_t * pages,size_t element_size,uint32_t element_num,qdf_dma_context_t memctxt,bool cacheable)1867 void qdf_mem_multi_pages_alloc(qdf_device_t osdev, 1868 struct qdf_mem_multi_page_t *pages, 1869 size_t element_size, uint32_t element_num, 1870 qdf_dma_context_t memctxt, bool cacheable) 1871 { 1872 uint16_t page_idx; 1873 struct qdf_mem_dma_page_t *dma_pages; 1874 void **cacheable_pages = NULL; 1875 uint16_t i; 1876 1877 if (!pages->page_size) 1878 pages->page_size = qdf_page_size; 1879 1880 pages->num_element_per_page = pages->page_size / element_size; 1881 if (!pages->num_element_per_page) { 1882 qdf_print("Invalid page %d or element size %d", 1883 (int)pages->page_size, (int)element_size); 1884 goto out_fail; 1885 } 1886 1887 pages->num_pages = element_num / pages->num_element_per_page; 1888 if (element_num % pages->num_element_per_page) 1889 pages->num_pages++; 1890 1891 if (cacheable) { 1892 /* Pages information storage */ 1893 pages->cacheable_pages = qdf_mem_malloc( 1894 pages->num_pages * sizeof(pages->cacheable_pages)); 1895 if (!pages->cacheable_pages) 1896 goto out_fail; 1897 1898 cacheable_pages = pages->cacheable_pages; 1899 for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { 1900 cacheable_pages[page_idx] = 1901 qdf_mem_malloc(pages->page_size); 1902 if (!cacheable_pages[page_idx]) 1903 goto page_alloc_fail; 1904 } 1905 pages->dma_pages = NULL; 1906 } else { 1907 pages->dma_pages = qdf_mem_malloc( 1908 pages->num_pages * sizeof(struct qdf_mem_dma_page_t)); 1909 if (!pages->dma_pages) 1910 goto out_fail; 1911 1912 dma_pages = pages->dma_pages; 1913 for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { 1914 dma_pages->page_v_addr_start = 1915 qdf_mem_alloc_consistent(osdev, osdev->dev, 1916 pages->page_size, 1917 &dma_pages->page_p_addr); 1918 if (!dma_pages->page_v_addr_start) { 1919 qdf_print("dmaable page alloc fail pi %d", 1920 page_idx); 1921 goto page_alloc_fail; 1922 } 1923 dma_pages->page_v_addr_end = 1924 dma_pages->page_v_addr_start + pages->page_size; 1925 dma_pages++; 1926 } 1927 pages->cacheable_pages = NULL; 1928 } 1929 return; 1930 1931 page_alloc_fail: 1932 if (cacheable) { 1933 for (i = 0; i < page_idx; i++) 1934 qdf_mem_free(pages->cacheable_pages[i]); 1935 qdf_mem_free(pages->cacheable_pages); 1936 } else { 1937 dma_pages = pages->dma_pages; 1938 for (i = 0; i < page_idx; i++) { 1939 qdf_mem_free_consistent( 1940 osdev, osdev->dev, pages->page_size, 1941 dma_pages->page_v_addr_start, 1942 dma_pages->page_p_addr, memctxt); 1943 dma_pages++; 1944 } 1945 qdf_mem_free(pages->dma_pages); 1946 } 1947 1948 out_fail: 1949 pages->cacheable_pages = NULL; 1950 pages->dma_pages = NULL; 1951 pages->num_pages = 0; 1952 return; 1953 } 1954 #else qdf_mem_multi_pages_alloc(qdf_device_t osdev,struct qdf_mem_multi_page_t * pages,size_t element_size,uint32_t element_num,qdf_dma_context_t memctxt,bool cacheable)1955 void qdf_mem_multi_pages_alloc(qdf_device_t osdev, 1956 struct qdf_mem_multi_page_t *pages, 1957 size_t element_size, uint32_t element_num, 1958 qdf_dma_context_t memctxt, bool cacheable) 1959 { 1960 uint16_t page_idx; 1961 struct qdf_mem_dma_page_t *dma_pages; 1962 void **cacheable_pages = NULL; 1963 uint16_t i; 1964 struct qdf_mem_dma_page_t temp_dma_pages; 1965 struct qdf_mem_dma_page_t *total_dma_pages = &temp_dma_pages; 1966 qdf_size_t total_size = 0; 1967 1968 pages->contiguous_dma_pages = false; 1969 1970 if (!pages->page_size) 1971 pages->page_size = qdf_page_size; 1972 1973 pages->num_element_per_page = pages->page_size / element_size; 1974 if (!pages->num_element_per_page) { 1975 qdf_print("Invalid page %d or element size %d", 1976 (int)pages->page_size, (int)element_size); 1977 goto out_fail; 1978 } 1979 1980 pages->num_pages = element_num / pages->num_element_per_page; 1981 if (element_num % pages->num_element_per_page) 1982 pages->num_pages++; 1983 1984 if (cacheable) { 1985 /* Pages information storage */ 1986 pages->cacheable_pages = qdf_mem_malloc( 1987 pages->num_pages * sizeof(pages->cacheable_pages)); 1988 if (!pages->cacheable_pages) 1989 goto out_fail; 1990 1991 cacheable_pages = pages->cacheable_pages; 1992 for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { 1993 cacheable_pages[page_idx] = 1994 qdf_mem_malloc(pages->page_size); 1995 if (!cacheable_pages[page_idx]) 1996 goto page_alloc_fail; 1997 } 1998 pages->dma_pages = NULL; 1999 } else { 2000 pages->dma_pages = qdf_mem_malloc( 2001 pages->num_pages * sizeof(struct qdf_mem_dma_page_t)); 2002 if (!pages->dma_pages) 2003 goto out_fail; 2004 2005 dma_pages = pages->dma_pages; 2006 total_size = pages->page_size * pages->num_pages; 2007 total_dma_pages->page_v_addr_start = 2008 qdf_mem_alloc_consistent(osdev, osdev->dev, 2009 total_size, 2010 &total_dma_pages->page_p_addr); 2011 total_dma_pages->page_v_addr_end = 2012 total_dma_pages->page_v_addr_start + total_size; 2013 if (!total_dma_pages->page_v_addr_start) { 2014 qdf_print("mem allocate fail, total_size: %zu", 2015 total_size); 2016 goto page_alloc_default; 2017 } 2018 2019 pages->contiguous_dma_pages = true; 2020 for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { 2021 dma_pages->page_v_addr_start = 2022 total_dma_pages->page_v_addr_start + 2023 (pages->page_size * page_idx); 2024 dma_pages->page_p_addr = 2025 total_dma_pages->page_p_addr + 2026 (pages->page_size * page_idx); 2027 dma_pages->page_v_addr_end = 2028 dma_pages->page_v_addr_start + pages->page_size; 2029 dma_pages++; 2030 } 2031 pages->cacheable_pages = NULL; 2032 return; 2033 2034 page_alloc_default: 2035 for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { 2036 dma_pages->page_v_addr_start = 2037 qdf_mem_alloc_consistent(osdev, osdev->dev, 2038 pages->page_size, 2039 &dma_pages->page_p_addr); 2040 if (!dma_pages->page_v_addr_start) { 2041 qdf_print("dmaable page alloc fail pi %d", 2042 page_idx); 2043 goto page_alloc_fail; 2044 } 2045 dma_pages->page_v_addr_end = 2046 dma_pages->page_v_addr_start + pages->page_size; 2047 dma_pages++; 2048 } 2049 pages->cacheable_pages = NULL; 2050 } 2051 return; 2052 2053 page_alloc_fail: 2054 if (cacheable) { 2055 for (i = 0; i < page_idx; i++) 2056 qdf_mem_free(pages->cacheable_pages[i]); 2057 qdf_mem_free(pages->cacheable_pages); 2058 } else { 2059 dma_pages = pages->dma_pages; 2060 for (i = 0; i < page_idx; i++) { 2061 qdf_mem_free_consistent( 2062 osdev, osdev->dev, pages->page_size, 2063 dma_pages->page_v_addr_start, 2064 dma_pages->page_p_addr, memctxt); 2065 dma_pages++; 2066 } 2067 qdf_mem_free(pages->dma_pages); 2068 } 2069 2070 out_fail: 2071 pages->cacheable_pages = NULL; 2072 pages->dma_pages = NULL; 2073 pages->num_pages = 0; 2074 } 2075 #endif 2076 qdf_export_symbol(qdf_mem_multi_pages_alloc); 2077 2078 #ifndef ALLOC_CONTIGUOUS_MULTI_PAGE qdf_mem_multi_pages_free(qdf_device_t osdev,struct qdf_mem_multi_page_t * pages,qdf_dma_context_t memctxt,bool cacheable)2079 void qdf_mem_multi_pages_free(qdf_device_t osdev, 2080 struct qdf_mem_multi_page_t *pages, 2081 qdf_dma_context_t memctxt, bool cacheable) 2082 { 2083 unsigned int page_idx; 2084 struct qdf_mem_dma_page_t *dma_pages; 2085 2086 if (!pages->page_size) 2087 pages->page_size = qdf_page_size; 2088 2089 if (cacheable) { 2090 for (page_idx = 0; page_idx < pages->num_pages; page_idx++) 2091 qdf_mem_free(pages->cacheable_pages[page_idx]); 2092 qdf_mem_free(pages->cacheable_pages); 2093 } else { 2094 dma_pages = pages->dma_pages; 2095 for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { 2096 qdf_mem_free_consistent( 2097 osdev, osdev->dev, pages->page_size, 2098 dma_pages->page_v_addr_start, 2099 dma_pages->page_p_addr, memctxt); 2100 dma_pages++; 2101 } 2102 qdf_mem_free(pages->dma_pages); 2103 } 2104 2105 pages->cacheable_pages = NULL; 2106 pages->dma_pages = NULL; 2107 pages->num_pages = 0; 2108 return; 2109 } 2110 #else qdf_mem_multi_pages_free(qdf_device_t osdev,struct qdf_mem_multi_page_t * pages,qdf_dma_context_t memctxt,bool cacheable)2111 void qdf_mem_multi_pages_free(qdf_device_t osdev, 2112 struct qdf_mem_multi_page_t *pages, 2113 qdf_dma_context_t memctxt, bool cacheable) 2114 { 2115 unsigned int page_idx; 2116 struct qdf_mem_dma_page_t *dma_pages; 2117 qdf_size_t total_size = 0; 2118 2119 if (!pages->page_size) 2120 pages->page_size = qdf_page_size; 2121 2122 if (cacheable) { 2123 for (page_idx = 0; page_idx < pages->num_pages; page_idx++) 2124 qdf_mem_free(pages->cacheable_pages[page_idx]); 2125 qdf_mem_free(pages->cacheable_pages); 2126 } else { 2127 dma_pages = pages->dma_pages; 2128 total_size = pages->page_size * pages->num_pages; 2129 if (pages->contiguous_dma_pages) { 2130 qdf_mem_free_consistent( 2131 osdev, osdev->dev, total_size, 2132 dma_pages->page_v_addr_start, 2133 dma_pages->page_p_addr, memctxt); 2134 goto pages_free_default; 2135 } 2136 for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { 2137 qdf_mem_free_consistent( 2138 osdev, osdev->dev, pages->page_size, 2139 dma_pages->page_v_addr_start, 2140 dma_pages->page_p_addr, memctxt); 2141 dma_pages++; 2142 } 2143 pages_free_default: 2144 qdf_mem_free(pages->dma_pages); 2145 } 2146 2147 pages->cacheable_pages = NULL; 2148 pages->dma_pages = NULL; 2149 pages->num_pages = 0; 2150 } 2151 #endif 2152 qdf_export_symbol(qdf_mem_multi_pages_free); 2153 #endif 2154 qdf_mem_multi_pages_zero(struct qdf_mem_multi_page_t * pages,bool cacheable)2155 void qdf_mem_multi_pages_zero(struct qdf_mem_multi_page_t *pages, 2156 bool cacheable) 2157 { 2158 unsigned int page_idx; 2159 struct qdf_mem_dma_page_t *dma_pages; 2160 2161 if (!pages->page_size) 2162 pages->page_size = qdf_page_size; 2163 2164 if (cacheable) { 2165 for (page_idx = 0; page_idx < pages->num_pages; page_idx++) 2166 qdf_mem_zero(pages->cacheable_pages[page_idx], 2167 pages->page_size); 2168 } else { 2169 dma_pages = pages->dma_pages; 2170 for (page_idx = 0; page_idx < pages->num_pages; page_idx++) { 2171 qdf_mem_zero(dma_pages->page_v_addr_start, 2172 pages->page_size); 2173 dma_pages++; 2174 } 2175 } 2176 } 2177 2178 qdf_export_symbol(qdf_mem_multi_pages_zero); 2179 __qdf_mem_free(void * ptr)2180 void __qdf_mem_free(void *ptr) 2181 { 2182 if (!ptr) 2183 return; 2184 2185 if (qdf_might_be_prealloc(ptr)) { 2186 if (qdf_mem_prealloc_put(ptr)) 2187 return; 2188 } 2189 2190 qdf_mem_kmalloc_dec(ksize(ptr)); 2191 2192 kfree(ptr); 2193 } 2194 2195 qdf_export_symbol(__qdf_mem_free); 2196 __qdf_mem_malloc(size_t size,const char * func,uint32_t line)2197 void *__qdf_mem_malloc(size_t size, const char *func, uint32_t line) 2198 { 2199 void *ptr; 2200 2201 if (!size || size > QDF_MEM_MAX_MALLOC) { 2202 qdf_nofl_err("Cannot malloc %zu bytes @ %s:%d", size, func, 2203 line); 2204 return NULL; 2205 } 2206 2207 ptr = qdf_mem_prealloc_get(size); 2208 if (ptr) 2209 return ptr; 2210 2211 ptr = kzalloc(size, qdf_mem_malloc_flags()); 2212 if (!ptr) 2213 return NULL; 2214 2215 qdf_mem_kmalloc_inc(ksize(ptr)); 2216 2217 return ptr; 2218 } 2219 2220 qdf_export_symbol(__qdf_mem_malloc); 2221 2222 #ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI __qdf_untracked_mem_free(void * ptr)2223 void __qdf_untracked_mem_free(void *ptr) 2224 { 2225 if (!ptr) 2226 return; 2227 2228 kfree(ptr); 2229 } 2230 __qdf_untracked_mem_malloc(size_t size,const char * func,uint32_t line)2231 void *__qdf_untracked_mem_malloc(size_t size, const char *func, uint32_t line) 2232 { 2233 void *ptr; 2234 2235 if (!size || size > QDF_MEM_MAX_MALLOC) { 2236 qdf_nofl_err("Cannot malloc %zu bytes @ %s:%d", size, func, 2237 line); 2238 return NULL; 2239 } 2240 2241 ptr = kzalloc(size, qdf_mem_malloc_flags()); 2242 if (!ptr) 2243 return NULL; 2244 2245 return ptr; 2246 } 2247 #endif 2248 qdf_aligned_malloc_fl(uint32_t * size,void ** vaddr_unaligned,qdf_dma_addr_t * paddr_unaligned,qdf_dma_addr_t * paddr_aligned,uint32_t align,const char * func,uint32_t line)2249 void *qdf_aligned_malloc_fl(uint32_t *size, 2250 void **vaddr_unaligned, 2251 qdf_dma_addr_t *paddr_unaligned, 2252 qdf_dma_addr_t *paddr_aligned, 2253 uint32_t align, 2254 const char *func, uint32_t line) 2255 { 2256 void *vaddr_aligned; 2257 uint32_t align_alloc_size; 2258 2259 *vaddr_unaligned = qdf_mem_malloc_fl((qdf_size_t)*size, func, 2260 line); 2261 if (!*vaddr_unaligned) { 2262 qdf_warn("Failed to alloc %uB @ %s:%d", *size, func, line); 2263 return NULL; 2264 } 2265 2266 *paddr_unaligned = qdf_mem_virt_to_phys(*vaddr_unaligned); 2267 2268 /* Re-allocate additional bytes to align base address only if 2269 * above allocation returns unaligned address. Reason for 2270 * trying exact size allocation above is, OS tries to allocate 2271 * blocks of size power-of-2 pages and then free extra pages. 2272 * e.g., of a ring size of 1MB, the allocation below will 2273 * request 1MB plus 7 bytes for alignment, which will cause a 2274 * 2MB block allocation,and that is failing sometimes due to 2275 * memory fragmentation. 2276 */ 2277 if ((unsigned long)(*paddr_unaligned) & (align - 1)) { 2278 align_alloc_size = *size + align - 1; 2279 2280 qdf_mem_free(*vaddr_unaligned); 2281 *vaddr_unaligned = qdf_mem_malloc_fl( 2282 (qdf_size_t)align_alloc_size, func, line); 2283 if (!*vaddr_unaligned) { 2284 qdf_warn("Failed to alloc %uB @ %s:%d", 2285 align_alloc_size, func, line); 2286 return NULL; 2287 } 2288 2289 *paddr_unaligned = qdf_mem_virt_to_phys( 2290 *vaddr_unaligned); 2291 *size = align_alloc_size; 2292 } 2293 2294 *paddr_aligned = (qdf_dma_addr_t)qdf_align 2295 ((unsigned long)(*paddr_unaligned), align); 2296 2297 vaddr_aligned = (void *)((unsigned long)(*vaddr_unaligned) + 2298 ((unsigned long)(*paddr_aligned) - 2299 (unsigned long)(*paddr_unaligned))); 2300 2301 return vaddr_aligned; 2302 } 2303 2304 qdf_export_symbol(qdf_aligned_malloc_fl); 2305 2306 #if defined(DP_UMAC_HW_RESET_SUPPORT) || defined(WLAN_SUPPORT_PPEDS) qdf_tx_desc_pool_free_bufs(void * ctxt,struct qdf_mem_multi_page_t * pages,uint32_t elem_size,uint32_t elem_count,uint8_t cacheable,qdf_mem_release_cb cb,void * elem_list)2307 int qdf_tx_desc_pool_free_bufs(void *ctxt, struct qdf_mem_multi_page_t *pages, 2308 uint32_t elem_size, uint32_t elem_count, 2309 uint8_t cacheable, qdf_mem_release_cb cb, 2310 void *elem_list) 2311 { 2312 uint16_t i, i_int; 2313 void *page_info; 2314 void *elem; 2315 uint32_t num_elem = 0; 2316 2317 for (i = 0; i < pages->num_pages; i++) { 2318 if (cacheable) 2319 page_info = pages->cacheable_pages[i]; 2320 else 2321 page_info = pages->dma_pages[i].page_v_addr_start; 2322 2323 if (!page_info) 2324 return -ENOMEM; 2325 2326 elem = page_info; 2327 for (i_int = 0; i_int < pages->num_element_per_page; i_int++) { 2328 cb(ctxt, elem, elem_list); 2329 elem = ((char *)elem + elem_size); 2330 num_elem++; 2331 2332 /* Number of desc pool elements reached */ 2333 if (num_elem == (elem_count - 1)) 2334 break; 2335 } 2336 } 2337 2338 return 0; 2339 } 2340 2341 qdf_export_symbol(qdf_tx_desc_pool_free_bufs); 2342 #endif 2343 qdf_mem_multi_page_link(qdf_device_t osdev,struct qdf_mem_multi_page_t * pages,uint32_t elem_size,uint32_t elem_count,uint8_t cacheable)2344 int qdf_mem_multi_page_link(qdf_device_t osdev, 2345 struct qdf_mem_multi_page_t *pages, 2346 uint32_t elem_size, uint32_t elem_count, 2347 uint8_t cacheable) 2348 { 2349 uint16_t i, i_int; 2350 void *page_info; 2351 void **c_elem = NULL; 2352 uint32_t num_link = 0; 2353 2354 for (i = 0; i < pages->num_pages; i++) { 2355 if (cacheable) 2356 page_info = pages->cacheable_pages[i]; 2357 else 2358 page_info = pages->dma_pages[i].page_v_addr_start; 2359 2360 if (!page_info) 2361 return -ENOMEM; 2362 2363 c_elem = (void **)page_info; 2364 for (i_int = 0; i_int < pages->num_element_per_page; i_int++) { 2365 if (i_int == (pages->num_element_per_page - 1)) { 2366 if ((i + 1) == pages->num_pages) 2367 break; 2368 if (cacheable) 2369 *c_elem = pages-> 2370 cacheable_pages[i + 1]; 2371 else 2372 *c_elem = pages-> 2373 dma_pages[i + 1]. 2374 page_v_addr_start; 2375 num_link++; 2376 break; 2377 } else { 2378 *c_elem = 2379 (void *)(((char *)c_elem) + elem_size); 2380 } 2381 num_link++; 2382 c_elem = (void **)*c_elem; 2383 2384 /* Last link established exit */ 2385 if (num_link == (elem_count - 1)) 2386 break; 2387 } 2388 } 2389 2390 if (c_elem) 2391 *c_elem = NULL; 2392 2393 return 0; 2394 } 2395 qdf_export_symbol(qdf_mem_multi_page_link); 2396 qdf_mem_copy(void * dst_addr,const void * src_addr,uint32_t num_bytes)2397 void qdf_mem_copy(void *dst_addr, const void *src_addr, uint32_t num_bytes) 2398 { 2399 /* special case where dst_addr or src_addr can be NULL */ 2400 if (!num_bytes) 2401 return; 2402 2403 QDF_BUG(dst_addr); 2404 QDF_BUG(src_addr); 2405 if (!dst_addr || !src_addr) 2406 return; 2407 2408 memcpy(dst_addr, src_addr, num_bytes); 2409 } 2410 qdf_export_symbol(qdf_mem_copy); 2411 qdf_mem_shared_mem_alloc(qdf_device_t osdev,uint32_t size)2412 qdf_shared_mem_t *qdf_mem_shared_mem_alloc(qdf_device_t osdev, uint32_t size) 2413 { 2414 qdf_shared_mem_t *shared_mem; 2415 qdf_dma_addr_t dma_addr, paddr; 2416 int ret; 2417 2418 shared_mem = qdf_mem_malloc(sizeof(*shared_mem)); 2419 if (!shared_mem) 2420 return NULL; 2421 2422 shared_mem->vaddr = qdf_mem_alloc_consistent(osdev, osdev->dev, 2423 size, qdf_mem_get_dma_addr_ptr(osdev, 2424 &shared_mem->mem_info)); 2425 if (!shared_mem->vaddr) { 2426 qdf_err("Unable to allocate DMA memory for shared resource"); 2427 qdf_mem_free(shared_mem); 2428 return NULL; 2429 } 2430 2431 qdf_mem_set_dma_size(osdev, &shared_mem->mem_info, size); 2432 size = qdf_mem_get_dma_size(osdev, &shared_mem->mem_info); 2433 2434 qdf_mem_zero(shared_mem->vaddr, size); 2435 dma_addr = qdf_mem_get_dma_addr(osdev, &shared_mem->mem_info); 2436 paddr = qdf_mem_paddr_from_dmaaddr(osdev, dma_addr); 2437 2438 qdf_mem_set_dma_pa(osdev, &shared_mem->mem_info, paddr); 2439 ret = qdf_mem_dma_get_sgtable(osdev->dev, &shared_mem->sgtable, 2440 shared_mem->vaddr, dma_addr, size); 2441 if (ret) { 2442 qdf_err("Unable to get DMA sgtable"); 2443 qdf_mem_free_consistent(osdev, osdev->dev, 2444 shared_mem->mem_info.size, 2445 shared_mem->vaddr, 2446 dma_addr, 2447 qdf_get_dma_mem_context(shared_mem, 2448 memctx)); 2449 qdf_mem_free(shared_mem); 2450 return NULL; 2451 } 2452 2453 qdf_dma_get_sgtable_dma_addr(&shared_mem->sgtable); 2454 2455 return shared_mem; 2456 } 2457 2458 qdf_export_symbol(qdf_mem_shared_mem_alloc); 2459 qdf_mem_copy_toio(void * dst_addr,const void * src_addr,uint32_t num_bytes)2460 void qdf_mem_copy_toio(void *dst_addr, const void *src_addr, uint32_t num_bytes) 2461 { 2462 if (0 == num_bytes) { 2463 /* special case where dst_addr or src_addr can be NULL */ 2464 return; 2465 } 2466 2467 if ((!dst_addr) || (!src_addr)) { 2468 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, 2469 "%s called with NULL parameter, source:%pK destination:%pK", 2470 __func__, src_addr, dst_addr); 2471 QDF_ASSERT(0); 2472 return; 2473 } 2474 memcpy_toio(dst_addr, src_addr, num_bytes); 2475 } 2476 2477 qdf_export_symbol(qdf_mem_copy_toio); 2478 qdf_mem_set_io(void * ptr,uint32_t num_bytes,uint32_t value)2479 void qdf_mem_set_io(void *ptr, uint32_t num_bytes, uint32_t value) 2480 { 2481 if (!ptr) { 2482 qdf_print("%s called with NULL parameter ptr", __func__); 2483 return; 2484 } 2485 memset_io(ptr, value, num_bytes); 2486 } 2487 2488 qdf_export_symbol(qdf_mem_set_io); 2489 qdf_mem_set(void * ptr,uint32_t num_bytes,uint32_t value)2490 void qdf_mem_set(void *ptr, uint32_t num_bytes, uint32_t value) 2491 { 2492 QDF_BUG(ptr); 2493 if (!ptr) 2494 return; 2495 2496 memset(ptr, value, num_bytes); 2497 } 2498 qdf_export_symbol(qdf_mem_set); 2499 qdf_mem_move(void * dst_addr,const void * src_addr,uint32_t num_bytes)2500 void qdf_mem_move(void *dst_addr, const void *src_addr, uint32_t num_bytes) 2501 { 2502 /* special case where dst_addr or src_addr can be NULL */ 2503 if (!num_bytes) 2504 return; 2505 2506 QDF_BUG(dst_addr); 2507 QDF_BUG(src_addr); 2508 if (!dst_addr || !src_addr) 2509 return; 2510 2511 memmove(dst_addr, src_addr, num_bytes); 2512 } 2513 qdf_export_symbol(qdf_mem_move); 2514 qdf_mem_cmp(const void * left,const void * right,size_t size)2515 int qdf_mem_cmp(const void *left, const void *right, size_t size) 2516 { 2517 QDF_BUG(left); 2518 QDF_BUG(right); 2519 2520 return memcmp(left, right, size); 2521 } 2522 qdf_export_symbol(qdf_mem_cmp); 2523 2524 #if defined(A_SIMOS_DEVHOST) || defined(HIF_SDIO) || defined(HIF_USB) 2525 /** 2526 * qdf_mem_dma_alloc() - allocates memory for dma 2527 * @osdev: OS device handle 2528 * @dev: Pointer to device handle 2529 * @size: Size to be allocated 2530 * @phy_addr: Physical address 2531 * 2532 * Return: pointer of allocated memory or null if memory alloc fails 2533 */ qdf_mem_dma_alloc(qdf_device_t osdev,void * dev,qdf_size_t size,qdf_dma_addr_t * phy_addr)2534 static inline void *qdf_mem_dma_alloc(qdf_device_t osdev, void *dev, 2535 qdf_size_t size, 2536 qdf_dma_addr_t *phy_addr) 2537 { 2538 void *vaddr; 2539 2540 vaddr = qdf_mem_malloc(size); 2541 *phy_addr = ((uintptr_t) vaddr); 2542 /* using this type conversion to suppress "cast from pointer to integer 2543 * of different size" warning on some platforms 2544 */ 2545 BUILD_BUG_ON(sizeof(*phy_addr) < sizeof(vaddr)); 2546 return vaddr; 2547 } 2548 2549 #elif defined(CONFIG_WIFI_EMULATION_WIFI_3_0) && defined(BUILD_X86) && \ 2550 !defined(QCA_WIFI_QCN9000) 2551 2552 #define QCA8074_RAM_BASE 0x50000000 2553 #define QDF_MEM_ALLOC_X86_MAX_RETRIES 10 qdf_mem_dma_alloc(qdf_device_t osdev,void * dev,qdf_size_t size,qdf_dma_addr_t * phy_addr)2554 void *qdf_mem_dma_alloc(qdf_device_t osdev, void *dev, qdf_size_t size, 2555 qdf_dma_addr_t *phy_addr) 2556 { 2557 void *vaddr = NULL; 2558 int i; 2559 2560 *phy_addr = 0; 2561 2562 for (i = 0; i < QDF_MEM_ALLOC_X86_MAX_RETRIES; i++) { 2563 vaddr = dma_alloc_coherent(dev, size, phy_addr, 2564 qdf_mem_malloc_flags()); 2565 2566 if (!vaddr) { 2567 qdf_err("%s failed , size: %zu!", __func__, size); 2568 return NULL; 2569 } 2570 2571 if (*phy_addr >= QCA8074_RAM_BASE) 2572 return vaddr; 2573 2574 dma_free_coherent(dev, size, vaddr, *phy_addr); 2575 } 2576 2577 return NULL; 2578 } 2579 #elif defined(QCA_DMA_PADDR_CHECK) 2580 #ifdef CONFIG_LEAK_DETECTION 2581 #define MAX_DEBUG_DOMAIN_COUNT QDF_DEBUG_DOMAIN_COUNT 2582 #define debug_domain_get() qdf_debug_domain_get() 2583 #else 2584 #define MAX_DEBUG_DOMAIN_COUNT 1 2585 #define debug_domain_get() DEFAULT_DEBUG_DOMAIN_INIT 2586 #endif 2587 /** 2588 * struct qdf_dma_buf_entry - DMA invalid buffer list entry 2589 * @node: QDF list node member 2590 * @size: DMA buffer size 2591 * @phy_addr: DMA buffer physical address 2592 * @vaddr: DMA buffer virtual address. if DMA buffer size is larger than entry 2593 * size, we use the DMA buffer to save entry info and the starting 2594 * address of the entry is the DMA buffer vaddr, in this way, we can 2595 * reduce unnecessary memory consumption. if DMA buffer size is smaller 2596 * than entry size, we need alloc another buffer, and vaddr will be set 2597 * to the invalid dma buffer virtual address. 2598 */ 2599 struct qdf_dma_buf_entry { 2600 qdf_list_node_t node; 2601 qdf_size_t size; 2602 qdf_dma_addr_t phy_addr; 2603 void *vaddr; 2604 }; 2605 2606 #define DMA_PHY_ADDR_RESERVED 0x2000 2607 #define QDF_DMA_MEM_ALLOC_MAX_RETRIES 10 2608 #define QDF_DMA_INVALID_BUF_LIST_SIZE 128 2609 static qdf_list_t qdf_invalid_buf_list[MAX_DEBUG_DOMAIN_COUNT]; 2610 static bool qdf_invalid_buf_list_init[MAX_DEBUG_DOMAIN_COUNT]; 2611 static qdf_spinlock_t qdf_invalid_buf_list_lock; 2612 qdf_mem_dma_alloc(qdf_device_t osdev,void * dev,qdf_size_t size,qdf_dma_addr_t * paddr)2613 static inline void *qdf_mem_dma_alloc(qdf_device_t osdev, void *dev, 2614 qdf_size_t size, qdf_dma_addr_t *paddr) 2615 { 2616 void *vaddr; 2617 uint32_t retry; 2618 QDF_STATUS status; 2619 bool is_separate; 2620 qdf_list_t *cur_buf_list; 2621 struct qdf_dma_buf_entry *entry; 2622 uint8_t current_domain; 2623 2624 for (retry = 0; retry < QDF_DMA_MEM_ALLOC_MAX_RETRIES; retry++) { 2625 vaddr = dma_alloc_coherent(dev, size, paddr, 2626 qdf_mem_malloc_flags()); 2627 if (!vaddr) 2628 return NULL; 2629 2630 if (qdf_likely(*paddr > DMA_PHY_ADDR_RESERVED)) 2631 return vaddr; 2632 2633 current_domain = debug_domain_get(); 2634 2635 /* if qdf_invalid_buf_list not init, so we can't store memory 2636 * info and can't hold it. let's free the invalid memory and 2637 * try to get memory with phy address greater than 2638 * DMA_PHY_ADDR_RESERVED 2639 */ 2640 if (current_domain >= MAX_DEBUG_DOMAIN_COUNT || 2641 !qdf_invalid_buf_list_init[current_domain]) { 2642 qdf_debug("physical address below 0x%x, re-alloc", 2643 DMA_PHY_ADDR_RESERVED); 2644 dma_free_coherent(dev, size, vaddr, *paddr); 2645 continue; 2646 } 2647 2648 cur_buf_list = &qdf_invalid_buf_list[current_domain]; 2649 if (size >= sizeof(*entry)) { 2650 entry = vaddr; 2651 entry->vaddr = NULL; 2652 } else { 2653 entry = qdf_mem_malloc(sizeof(*entry)); 2654 if (!entry) { 2655 dma_free_coherent(dev, size, vaddr, *paddr); 2656 qdf_err("qdf_mem_malloc entry failed!"); 2657 continue; 2658 } 2659 entry->vaddr = vaddr; 2660 } 2661 2662 entry->phy_addr = *paddr; 2663 entry->size = size; 2664 qdf_spin_lock_irqsave(&qdf_invalid_buf_list_lock); 2665 status = qdf_list_insert_back(cur_buf_list, 2666 &entry->node); 2667 qdf_spin_unlock_irqrestore(&qdf_invalid_buf_list_lock); 2668 if (QDF_IS_STATUS_ERROR(status)) { 2669 qdf_err("insert buf entry fail, status %d", status); 2670 is_separate = !entry->vaddr ? false : true; 2671 dma_free_coherent(dev, size, vaddr, *paddr); 2672 if (is_separate) 2673 qdf_mem_free(entry); 2674 } 2675 } 2676 2677 return NULL; 2678 } 2679 #else qdf_mem_dma_alloc(qdf_device_t osdev,void * dev,qdf_size_t size,qdf_dma_addr_t * paddr)2680 static inline void *qdf_mem_dma_alloc(qdf_device_t osdev, void *dev, 2681 qdf_size_t size, qdf_dma_addr_t *paddr) 2682 { 2683 return dma_alloc_coherent(dev, size, paddr, qdf_mem_malloc_flags()); 2684 } 2685 #endif 2686 2687 #if defined(A_SIMOS_DEVHOST) || defined(HIF_SDIO) || defined(HIF_USB) 2688 static inline void qdf_mem_dma_free(void * dev,qdf_size_t size,void * vaddr,qdf_dma_addr_t paddr)2689 qdf_mem_dma_free(void *dev, qdf_size_t size, void *vaddr, qdf_dma_addr_t paddr) 2690 { 2691 qdf_mem_free(vaddr); 2692 } 2693 #else 2694 2695 static inline void qdf_mem_dma_free(void * dev,qdf_size_t size,void * vaddr,qdf_dma_addr_t paddr)2696 qdf_mem_dma_free(void *dev, qdf_size_t size, void *vaddr, qdf_dma_addr_t paddr) 2697 { 2698 dma_free_coherent(dev, size, vaddr, paddr); 2699 } 2700 #endif 2701 2702 #ifdef MEMORY_DEBUG qdf_mem_alloc_consistent_debug(qdf_device_t osdev,void * dev,qdf_size_t size,qdf_dma_addr_t * paddr,const char * func,uint32_t line,void * caller)2703 void *qdf_mem_alloc_consistent_debug(qdf_device_t osdev, void *dev, 2704 qdf_size_t size, qdf_dma_addr_t *paddr, 2705 const char *func, uint32_t line, 2706 void *caller) 2707 { 2708 QDF_STATUS status; 2709 enum qdf_debug_domain current_domain = qdf_debug_domain_get(); 2710 qdf_list_t *mem_list = qdf_mem_dma_list(current_domain); 2711 struct qdf_mem_header *header; 2712 void *vaddr; 2713 2714 if (is_initial_mem_debug_disabled) 2715 return __qdf_mem_alloc_consistent(osdev, dev, 2716 size, paddr, 2717 func, line); 2718 2719 if (!size || size > QDF_MEM_MAX_MALLOC) { 2720 qdf_err("Cannot malloc %zu bytes @ %s:%d", size, func, line); 2721 return NULL; 2722 } 2723 2724 vaddr = qdf_mem_dma_alloc(osdev, dev, size + QDF_DMA_MEM_DEBUG_SIZE, 2725 paddr); 2726 2727 if (!vaddr) { 2728 qdf_warn("Failed to malloc %zuB @ %s:%d", size, func, line); 2729 return NULL; 2730 } 2731 2732 header = qdf_mem_dma_get_header(vaddr, size); 2733 /* For DMA buffers we only add trailers, this function will init 2734 * the header structure at the tail 2735 * Prefix the header into DMA buffer causes SMMU faults, so 2736 * do not prefix header into the DMA buffers 2737 */ 2738 qdf_mem_header_init(header, size, func, line, caller); 2739 2740 qdf_spin_lock_irqsave(&qdf_mem_dma_list_lock); 2741 status = qdf_list_insert_front(mem_list, &header->node); 2742 qdf_spin_unlock_irqrestore(&qdf_mem_dma_list_lock); 2743 if (QDF_IS_STATUS_ERROR(status)) 2744 qdf_err("Failed to insert memory header; status %d", status); 2745 2746 qdf_mem_dma_inc(size); 2747 2748 return vaddr; 2749 } 2750 qdf_export_symbol(qdf_mem_alloc_consistent_debug); 2751 qdf_mem_free_consistent_debug(qdf_device_t osdev,void * dev,qdf_size_t size,void * vaddr,qdf_dma_addr_t paddr,qdf_dma_context_t memctx,const char * func,uint32_t line)2752 void qdf_mem_free_consistent_debug(qdf_device_t osdev, void *dev, 2753 qdf_size_t size, void *vaddr, 2754 qdf_dma_addr_t paddr, 2755 qdf_dma_context_t memctx, 2756 const char *func, uint32_t line) 2757 { 2758 enum qdf_debug_domain domain = qdf_debug_domain_get(); 2759 struct qdf_mem_header *header; 2760 enum qdf_mem_validation_bitmap error_bitmap; 2761 2762 if (is_initial_mem_debug_disabled) { 2763 __qdf_mem_free_consistent( 2764 osdev, dev, 2765 size, vaddr, 2766 paddr, memctx); 2767 return; 2768 } 2769 2770 /* freeing a null pointer is valid */ 2771 if (qdf_unlikely(!vaddr)) 2772 return; 2773 2774 qdf_talloc_assert_no_children_fl(vaddr, func, line); 2775 2776 qdf_spin_lock_irqsave(&qdf_mem_dma_list_lock); 2777 /* For DMA buffers we only add trailers, this function will retrieve 2778 * the header structure at the tail 2779 * Prefix the header into DMA buffer causes SMMU faults, so 2780 * do not prefix header into the DMA buffers 2781 */ 2782 header = qdf_mem_dma_get_header(vaddr, size); 2783 error_bitmap = qdf_mem_header_validate(header, domain); 2784 if (!error_bitmap) { 2785 header->freed = true; 2786 qdf_list_remove_node(qdf_mem_dma_list(header->domain), 2787 &header->node); 2788 } 2789 qdf_spin_unlock_irqrestore(&qdf_mem_dma_list_lock); 2790 2791 qdf_mem_header_assert_valid(header, domain, error_bitmap, func, line); 2792 2793 qdf_mem_dma_dec(header->size); 2794 qdf_mem_dma_free(dev, size + QDF_DMA_MEM_DEBUG_SIZE, vaddr, paddr); 2795 } 2796 qdf_export_symbol(qdf_mem_free_consistent_debug); 2797 #endif /* MEMORY_DEBUG */ 2798 __qdf_mem_free_consistent(qdf_device_t osdev,void * dev,qdf_size_t size,void * vaddr,qdf_dma_addr_t paddr,qdf_dma_context_t memctx)2799 void __qdf_mem_free_consistent(qdf_device_t osdev, void *dev, 2800 qdf_size_t size, void *vaddr, 2801 qdf_dma_addr_t paddr, qdf_dma_context_t memctx) 2802 { 2803 qdf_mem_dma_dec(size); 2804 qdf_mem_dma_free(dev, size, vaddr, paddr); 2805 } 2806 2807 qdf_export_symbol(__qdf_mem_free_consistent); 2808 __qdf_mem_alloc_consistent(qdf_device_t osdev,void * dev,qdf_size_t size,qdf_dma_addr_t * paddr,const char * func,uint32_t line)2809 void *__qdf_mem_alloc_consistent(qdf_device_t osdev, void *dev, 2810 qdf_size_t size, qdf_dma_addr_t *paddr, 2811 const char *func, uint32_t line) 2812 { 2813 void *vaddr; 2814 2815 if (!size || size > QDF_MEM_MAX_MALLOC) { 2816 qdf_nofl_err("Cannot malloc %zu bytes @ %s:%d", 2817 size, func, line); 2818 return NULL; 2819 } 2820 2821 vaddr = qdf_mem_dma_alloc(osdev, dev, size, paddr); 2822 2823 if (vaddr) 2824 qdf_mem_dma_inc(size); 2825 2826 return vaddr; 2827 } 2828 2829 qdf_export_symbol(__qdf_mem_alloc_consistent); 2830 qdf_aligned_mem_alloc_consistent_fl(qdf_device_t osdev,uint32_t * size,void ** vaddr_unaligned,qdf_dma_addr_t * paddr_unaligned,qdf_dma_addr_t * paddr_aligned,uint32_t align,const char * func,uint32_t line)2831 void *qdf_aligned_mem_alloc_consistent_fl( 2832 qdf_device_t osdev, uint32_t *size, 2833 void **vaddr_unaligned, qdf_dma_addr_t *paddr_unaligned, 2834 qdf_dma_addr_t *paddr_aligned, uint32_t align, 2835 const char *func, uint32_t line) 2836 { 2837 void *vaddr_aligned; 2838 uint32_t align_alloc_size; 2839 2840 *vaddr_unaligned = qdf_mem_alloc_consistent( 2841 osdev, osdev->dev, (qdf_size_t)*size, paddr_unaligned); 2842 if (!*vaddr_unaligned) { 2843 qdf_warn("Failed to alloc %uB @ %s:%d", 2844 *size, func, line); 2845 return NULL; 2846 } 2847 2848 /* Re-allocate additional bytes to align base address only if 2849 * above allocation returns unaligned address. Reason for 2850 * trying exact size allocation above is, OS tries to allocate 2851 * blocks of size power-of-2 pages and then free extra pages. 2852 * e.g., of a ring size of 1MB, the allocation below will 2853 * request 1MB plus 7 bytes for alignment, which will cause a 2854 * 2MB block allocation,and that is failing sometimes due to 2855 * memory fragmentation. 2856 */ 2857 if ((unsigned long)(*paddr_unaligned) & (align - 1)) { 2858 align_alloc_size = *size + align - 1; 2859 2860 qdf_mem_free_consistent(osdev, osdev->dev, *size, 2861 *vaddr_unaligned, 2862 *paddr_unaligned, 0); 2863 2864 *vaddr_unaligned = qdf_mem_alloc_consistent( 2865 osdev, osdev->dev, align_alloc_size, 2866 paddr_unaligned); 2867 if (!*vaddr_unaligned) { 2868 qdf_warn("Failed to alloc %uB @ %s:%d", 2869 align_alloc_size, func, line); 2870 return NULL; 2871 } 2872 2873 *size = align_alloc_size; 2874 } 2875 2876 *paddr_aligned = (qdf_dma_addr_t)qdf_align( 2877 (unsigned long)(*paddr_unaligned), align); 2878 2879 vaddr_aligned = (void *)((unsigned long)(*vaddr_unaligned) + 2880 ((unsigned long)(*paddr_aligned) - 2881 (unsigned long)(*paddr_unaligned))); 2882 2883 return vaddr_aligned; 2884 } 2885 qdf_export_symbol(qdf_aligned_mem_alloc_consistent_fl); 2886 qdf_mem_dma_sync_single_for_device(qdf_device_t osdev,qdf_dma_addr_t bus_addr,qdf_size_t size,enum dma_data_direction direction)2887 void qdf_mem_dma_sync_single_for_device(qdf_device_t osdev, 2888 qdf_dma_addr_t bus_addr, 2889 qdf_size_t size, 2890 enum dma_data_direction direction) 2891 { 2892 dma_sync_single_for_device(osdev->dev, bus_addr, size, direction); 2893 } 2894 qdf_export_symbol(qdf_mem_dma_sync_single_for_device); 2895 qdf_mem_dma_sync_single_for_cpu(qdf_device_t osdev,qdf_dma_addr_t bus_addr,qdf_size_t size,enum dma_data_direction direction)2896 void qdf_mem_dma_sync_single_for_cpu(qdf_device_t osdev, 2897 qdf_dma_addr_t bus_addr, 2898 qdf_size_t size, 2899 enum dma_data_direction direction) 2900 { 2901 dma_sync_single_for_cpu(osdev->dev, bus_addr, size, direction); 2902 } 2903 qdf_export_symbol(qdf_mem_dma_sync_single_for_cpu); 2904 qdf_mem_init(void)2905 void qdf_mem_init(void) 2906 { 2907 qdf_mem_debug_init(); 2908 qdf_net_buf_debug_init(); 2909 qdf_frag_debug_init(); 2910 qdf_mem_debugfs_init(); 2911 qdf_mem_debug_debugfs_init(); 2912 } 2913 qdf_export_symbol(qdf_mem_init); 2914 qdf_mem_exit(void)2915 void qdf_mem_exit(void) 2916 { 2917 qdf_mem_debug_debugfs_exit(); 2918 qdf_mem_debugfs_exit(); 2919 qdf_frag_debug_exit(); 2920 qdf_net_buf_debug_exit(); 2921 qdf_mem_debug_exit(); 2922 } 2923 qdf_export_symbol(qdf_mem_exit); 2924 qdf_ether_addr_copy(void * dst_addr,const void * src_addr)2925 void qdf_ether_addr_copy(void *dst_addr, const void *src_addr) 2926 { 2927 if ((!dst_addr) || (!src_addr)) { 2928 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, 2929 "%s called with NULL parameter, source:%pK destination:%pK", 2930 __func__, src_addr, dst_addr); 2931 QDF_ASSERT(0); 2932 return; 2933 } 2934 ether_addr_copy(dst_addr, src_addr); 2935 } 2936 qdf_export_symbol(qdf_ether_addr_copy); 2937 qdf_dma_mem_stats_read(void)2938 int32_t qdf_dma_mem_stats_read(void) 2939 { 2940 return qdf_atomic_read(&qdf_mem_stat.dma); 2941 } 2942 2943 qdf_export_symbol(qdf_dma_mem_stats_read); 2944 qdf_heap_mem_stats_read(void)2945 int32_t qdf_heap_mem_stats_read(void) 2946 { 2947 return qdf_atomic_read(&qdf_mem_stat.kmalloc); 2948 } 2949 2950 qdf_export_symbol(qdf_heap_mem_stats_read); 2951 qdf_skb_mem_stats_read(void)2952 int32_t qdf_skb_mem_stats_read(void) 2953 { 2954 return qdf_atomic_read(&qdf_mem_stat.skb); 2955 } 2956 2957 qdf_export_symbol(qdf_skb_mem_stats_read); 2958 qdf_skb_total_mem_stats_read(void)2959 int32_t qdf_skb_total_mem_stats_read(void) 2960 { 2961 return qdf_atomic_read(&qdf_mem_stat.skb_total); 2962 } 2963 2964 qdf_export_symbol(qdf_skb_total_mem_stats_read); 2965 qdf_skb_max_mem_stats_read(void)2966 int32_t qdf_skb_max_mem_stats_read(void) 2967 { 2968 return qdf_mem_stat.skb_mem_max; 2969 } 2970 2971 qdf_export_symbol(qdf_skb_max_mem_stats_read); 2972 qdf_dp_tx_skb_mem_stats_read(void)2973 int32_t qdf_dp_tx_skb_mem_stats_read(void) 2974 { 2975 return qdf_atomic_read(&qdf_mem_stat.dp_tx_skb); 2976 } 2977 2978 qdf_export_symbol(qdf_dp_tx_skb_mem_stats_read); 2979 qdf_dp_rx_skb_mem_stats_read(void)2980 int32_t qdf_dp_rx_skb_mem_stats_read(void) 2981 { 2982 return qdf_atomic_read(&qdf_mem_stat.dp_rx_skb); 2983 } 2984 2985 qdf_export_symbol(qdf_dp_rx_skb_mem_stats_read); 2986 qdf_mem_dp_tx_skb_cnt_read(void)2987 int32_t qdf_mem_dp_tx_skb_cnt_read(void) 2988 { 2989 return qdf_atomic_read(&qdf_mem_stat.dp_tx_skb_count); 2990 } 2991 2992 qdf_export_symbol(qdf_mem_dp_tx_skb_cnt_read); 2993 qdf_mem_dp_tx_skb_max_cnt_read(void)2994 int32_t qdf_mem_dp_tx_skb_max_cnt_read(void) 2995 { 2996 return qdf_mem_stat.dp_tx_skb_count_max; 2997 } 2998 2999 qdf_export_symbol(qdf_mem_dp_tx_skb_max_cnt_read); 3000 qdf_mem_dp_rx_skb_cnt_read(void)3001 int32_t qdf_mem_dp_rx_skb_cnt_read(void) 3002 { 3003 return qdf_atomic_read(&qdf_mem_stat.dp_rx_skb_count); 3004 } 3005 3006 qdf_export_symbol(qdf_mem_dp_rx_skb_cnt_read); 3007 qdf_mem_dp_rx_skb_max_cnt_read(void)3008 int32_t qdf_mem_dp_rx_skb_max_cnt_read(void) 3009 { 3010 return qdf_mem_stat.dp_rx_skb_count_max; 3011 } 3012 3013 qdf_export_symbol(qdf_mem_dp_rx_skb_max_cnt_read); 3014 qdf_dp_tx_skb_max_mem_stats_read(void)3015 int32_t qdf_dp_tx_skb_max_mem_stats_read(void) 3016 { 3017 return qdf_mem_stat.dp_tx_skb_mem_max; 3018 } 3019 3020 qdf_export_symbol(qdf_dp_tx_skb_max_mem_stats_read); 3021 qdf_dp_rx_skb_max_mem_stats_read(void)3022 int32_t qdf_dp_rx_skb_max_mem_stats_read(void) 3023 { 3024 return qdf_mem_stat.dp_rx_skb_mem_max; 3025 } 3026 3027 qdf_export_symbol(qdf_dp_rx_skb_max_mem_stats_read); 3028 qdf_mem_tx_desc_cnt_read(void)3029 int32_t qdf_mem_tx_desc_cnt_read(void) 3030 { 3031 return qdf_atomic_read(&qdf_mem_stat.tx_descs_outstanding); 3032 } 3033 3034 qdf_export_symbol(qdf_mem_tx_desc_cnt_read); 3035 qdf_mem_tx_desc_max_read(void)3036 int32_t qdf_mem_tx_desc_max_read(void) 3037 { 3038 return qdf_mem_stat.tx_descs_max; 3039 } 3040 3041 qdf_export_symbol(qdf_mem_tx_desc_max_read); 3042 qdf_mem_tx_desc_cnt_update(qdf_atomic_t pending_tx_descs,int32_t tx_descs_max)3043 void qdf_mem_tx_desc_cnt_update(qdf_atomic_t pending_tx_descs, 3044 int32_t tx_descs_max) 3045 { 3046 qdf_mem_stat.tx_descs_outstanding = pending_tx_descs; 3047 qdf_mem_stat.tx_descs_max = tx_descs_max; 3048 } 3049 3050 qdf_export_symbol(qdf_mem_tx_desc_cnt_update); 3051 qdf_mem_stats_init(void)3052 void qdf_mem_stats_init(void) 3053 { 3054 qdf_mem_stat.skb_mem_max = 0; 3055 qdf_mem_stat.dp_tx_skb_mem_max = 0; 3056 qdf_mem_stat.dp_rx_skb_mem_max = 0; 3057 qdf_mem_stat.dp_tx_skb_count_max = 0; 3058 qdf_mem_stat.dp_rx_skb_count_max = 0; 3059 qdf_mem_stat.tx_descs_max = 0; 3060 } 3061 3062 qdf_export_symbol(qdf_mem_stats_init); 3063 __qdf_mem_valloc(size_t size,const char * func,uint32_t line)3064 void *__qdf_mem_valloc(size_t size, const char *func, uint32_t line) 3065 { 3066 void *ptr; 3067 3068 if (!size) { 3069 qdf_err("Valloc called with 0 bytes @ %s:%d", func, line); 3070 return NULL; 3071 } 3072 3073 ptr = vzalloc(size); 3074 3075 return ptr; 3076 } 3077 3078 qdf_export_symbol(__qdf_mem_valloc); 3079 __qdf_mem_vfree(void * ptr)3080 void __qdf_mem_vfree(void *ptr) 3081 { 3082 if (qdf_unlikely(!ptr)) 3083 return; 3084 3085 vfree(ptr); 3086 } 3087 3088 qdf_export_symbol(__qdf_mem_vfree); 3089 3090 #if IS_ENABLED(CONFIG_ARM_SMMU) && defined(ENABLE_SMMU_S1_TRANSLATION) 3091 int qdf_iommu_domain_get_attr(qdf_iommu_domain_t * domain,enum qdf_iommu_attr attr,void * data)3092 qdf_iommu_domain_get_attr(qdf_iommu_domain_t *domain, 3093 enum qdf_iommu_attr attr, void *data) 3094 { 3095 return __qdf_iommu_domain_get_attr(domain, attr, data); 3096 } 3097 3098 qdf_export_symbol(qdf_iommu_domain_get_attr); 3099 #endif 3100 3101 #ifdef ENHANCED_OS_ABSTRACTION qdf_update_mem_map_table(qdf_device_t osdev,qdf_mem_info_t * mem_info,qdf_dma_addr_t dma_addr,uint32_t mem_size)3102 void qdf_update_mem_map_table(qdf_device_t osdev, 3103 qdf_mem_info_t *mem_info, 3104 qdf_dma_addr_t dma_addr, 3105 uint32_t mem_size) 3106 { 3107 if (!mem_info) { 3108 qdf_nofl_err("%s: NULL mem_info", __func__); 3109 return; 3110 } 3111 3112 __qdf_update_mem_map_table(osdev, mem_info, dma_addr, mem_size); 3113 } 3114 3115 qdf_export_symbol(qdf_update_mem_map_table); 3116 qdf_mem_paddr_from_dmaaddr(qdf_device_t osdev,qdf_dma_addr_t dma_addr)3117 qdf_dma_addr_t qdf_mem_paddr_from_dmaaddr(qdf_device_t osdev, 3118 qdf_dma_addr_t dma_addr) 3119 { 3120 return __qdf_mem_paddr_from_dmaaddr(osdev, dma_addr); 3121 } 3122 3123 qdf_export_symbol(qdf_mem_paddr_from_dmaaddr); 3124 #endif 3125 3126 #ifdef QCA_KMEM_CACHE_SUPPORT 3127 qdf_kmem_cache_t __qdf_kmem_cache_create(const char * cache_name,qdf_size_t size)3128 __qdf_kmem_cache_create(const char *cache_name, 3129 qdf_size_t size) 3130 { 3131 struct kmem_cache *cache; 3132 3133 cache = kmem_cache_create(cache_name, size, 3134 0, 0, NULL); 3135 3136 if (!cache) 3137 return NULL; 3138 3139 return cache; 3140 } 3141 qdf_export_symbol(__qdf_kmem_cache_create); 3142 3143 void __qdf_kmem_cache_destroy(qdf_kmem_cache_t cache)3144 __qdf_kmem_cache_destroy(qdf_kmem_cache_t cache) 3145 { 3146 kmem_cache_destroy(cache); 3147 } 3148 3149 qdf_export_symbol(__qdf_kmem_cache_destroy); 3150 3151 void* __qdf_kmem_cache_alloc(qdf_kmem_cache_t cache)3152 __qdf_kmem_cache_alloc(qdf_kmem_cache_t cache) 3153 { 3154 int flags = GFP_KERNEL; 3155 3156 if (in_interrupt() || irqs_disabled() || in_atomic()) 3157 flags = GFP_ATOMIC; 3158 3159 return kmem_cache_alloc(cache, flags); 3160 } 3161 3162 qdf_export_symbol(__qdf_kmem_cache_alloc); 3163 3164 void __qdf_kmem_cache_free(qdf_kmem_cache_t cache,void * node)3165 __qdf_kmem_cache_free(qdf_kmem_cache_t cache, void *node) 3166 3167 { 3168 kmem_cache_free(cache, node); 3169 } 3170 3171 qdf_export_symbol(__qdf_kmem_cache_free); 3172 #else 3173 qdf_kmem_cache_t __qdf_kmem_cache_create(const char * cache_name,qdf_size_t size)3174 __qdf_kmem_cache_create(const char *cache_name, 3175 qdf_size_t size) 3176 { 3177 return NULL; 3178 } 3179 3180 void __qdf_kmem_cache_destroy(qdf_kmem_cache_t cache)3181 __qdf_kmem_cache_destroy(qdf_kmem_cache_t cache) 3182 { 3183 } 3184 3185 void * __qdf_kmem_cache_alloc(qdf_kmem_cache_t cache)3186 __qdf_kmem_cache_alloc(qdf_kmem_cache_t cache) 3187 { 3188 return NULL; 3189 } 3190 3191 void __qdf_kmem_cache_free(qdf_kmem_cache_t cache,void * node)3192 __qdf_kmem_cache_free(qdf_kmem_cache_t cache, void *node) 3193 { 3194 } 3195 #endif 3196 3197 #ifdef QCA_DMA_PADDR_CHECK qdf_dma_invalid_buf_list_init(void)3198 void qdf_dma_invalid_buf_list_init(void) 3199 { 3200 int i; 3201 3202 for (i = 0; i < MAX_DEBUG_DOMAIN_COUNT; i++) { 3203 qdf_list_create(&qdf_invalid_buf_list[i], 3204 QDF_DMA_INVALID_BUF_LIST_SIZE); 3205 qdf_invalid_buf_list_init[i] = true; 3206 } 3207 qdf_spinlock_create(&qdf_invalid_buf_list_lock); 3208 } 3209 qdf_dma_invalid_buf_free(void * dev,uint8_t domain)3210 void qdf_dma_invalid_buf_free(void *dev, uint8_t domain) 3211 { 3212 bool is_separate; 3213 qdf_list_t *cur_buf_list; 3214 struct qdf_dma_buf_entry *entry; 3215 QDF_STATUS status = QDF_STATUS_E_EMPTY; 3216 3217 if (!dev) 3218 return; 3219 3220 if (domain >= MAX_DEBUG_DOMAIN_COUNT) 3221 return; 3222 3223 if (!qdf_invalid_buf_list_init[domain]) 3224 return; 3225 3226 cur_buf_list = &qdf_invalid_buf_list[domain]; 3227 do { 3228 qdf_spin_lock_irqsave(&qdf_invalid_buf_list_lock); 3229 status = qdf_list_remove_front(cur_buf_list, 3230 (qdf_list_node_t **)&entry); 3231 qdf_spin_unlock_irqrestore(&qdf_invalid_buf_list_lock); 3232 3233 if (status != QDF_STATUS_SUCCESS) 3234 break; 3235 3236 is_separate = !entry->vaddr ? false : true; 3237 if (is_separate) { 3238 dma_free_coherent(dev, entry->size, entry->vaddr, 3239 entry->phy_addr); 3240 qdf_mem_free(entry); 3241 } else 3242 dma_free_coherent(dev, entry->size, entry, 3243 entry->phy_addr); 3244 } while (!qdf_list_empty(cur_buf_list)); 3245 qdf_invalid_buf_list_init[domain] = false; 3246 } 3247 qdf_dma_invalid_buf_list_deinit(void)3248 void qdf_dma_invalid_buf_list_deinit(void) 3249 { 3250 int i; 3251 3252 for (i = 0; i < MAX_DEBUG_DOMAIN_COUNT; i++) 3253 qdf_list_destroy(&qdf_invalid_buf_list[i]); 3254 3255 qdf_spinlock_destroy(&qdf_invalid_buf_list_lock); 3256 } 3257 #endif /* QCA_DMA_PADDR_CHECK */ 3258