【C语言】Infiniband驱动mlx4_reset

news2024/11/25 14:38:53

一、注释

这个 mlx4_reset 函数负责重置 Mellanox 设备。它保存了设备的 PCI 头信息,然后重置了设备,之后还原保存的 PCI 头信息。请注意,该函数是用英文注释的,下面提供中文注释的版本。以下是该函数的流程:
1. 为保存 PCI 头信息分配内存。
2. 如果存在 PCI Express 能力结构,则保存 PCI 头信息。
3. 映射硬件重置寄存器地址空间。
4. 获取硬件信号量以防止闪存更新期间冲突。
5. 实际执行硬件重置操作。
6. 等待一段时间以确保设备重置完成。
7. 检查设备是否恢复到操作状态。
8. 如果设备已经恢复操作状态,则还原 PCI 头信息。
9. 清理和释放所有分配的资源。
以下是注释翻译成中文后的代码片段:

int mlx4_reset(struct mlx4_dev *dev) {
    // ...之前的代码略...

    /* 实际执行硬件重置 */
    writel(MLX4_RESET_VALUE, reset + MLX4_RESET_OFFSET);
    iounmap(reset);

    /* 文档称重置后应等待一秒钟才能访问设备 */
    msleep(1000);

    // ...之后的代码略...

    /* 现在恢复 PCI 头信息 */
    if (pcie_cap) {
        // 恢复 PCI Express Device Control 寄存器
        devctl = hca_header[(pcie_cap + PCI_EXP_DEVCTL) / 4];
        if (pcie_capability_write_word(dev->persist->pdev,
                                       PCI_EXP_DEVCTL,
                                       devctl)) {
            err = -ENODEV;
            mlx4_err(dev, "无法恢复 HCA PCI Express 设备控制寄存器,中止操作\n");
            goto out;
        }
        // 恢复 PCI Express Link Control 寄存器
        linkctl = hca_header[(pcie_cap + PCI_EXP_LNKCTL) / 4];
        if (pcie_capability_write_word(dev->persist->pdev,
                                       PCI_EXP_LNKCTL,
                                       linkctl)) {
            err = -ENODEV;
            mlx4_err(dev, "无法恢复 HCA PCI Express 链接控制寄存器,中止操作\n");
            goto out;
        }
    }

    // ...之后的清理代码略...

    return err;
}

请注意,这些注释更确切地描述了代码中的每个重要步骤,并对原开发者的注释进行翻译以更好地帮助中文读者理解代码。在 Linux 内核代码中,通常不鼓励添加太多注释,而是倾向于通过代码清晰表达意图。不过,如果在维护的项目中需要用中文注释,可以按照实际情况将代码中的关键部分翻译成中文。

注释,对关键代码部分进行解释:

#include <linux/errno.h>  // 包含Linux内核的错误号定义
#include <linux/pci.h>    // 包含用于PCI操作的函数和宏定义
#include <linux/delay.h>  // 包含延时函数
#include <linux/slab.h>   // 包含内存分配函数
#include <linux/jiffies.h>// 包含时间管理函数和宏

#include "mlx4.h" // 包含mlx4驱动的定义和声明

// 定义重置操作需要用到的常量
#define MLX4_RESET_BASE             0xf0000
#define MLX4_RESET_SIZE             0x400
#define MLX4_SEM_OFFSET             0x3fc
#define MLX4_RESET_OFFSET           0x10
#define MLX4_RESET_VALUE            swab32(1)

#define MLX4_SEM_TIMEOUT_JIFFIES    (10 * HZ)
#define MLX4_RESET_TIMEOUT_JIFFIES  (2 * HZ)

int mlx4_reset(struct mlx4_dev *dev)
{
    // 变量定义
    void __iomem *reset;     // 映射重置寄存器的地址
    u32 *hca_header = NULL;  // 存储设备PCI头信息的缓冲区
    int pcie_cap;
    u16 devctl, linkctl, vendor;
    unsigned long end;
    u32 sem;
    int i;
    int err = 0;
    // 以下是函数主要逻辑
    // 动态分配256字节的内存用于存储PCI头信息
    hca_header = kmalloc(256, GFP_KERNEL); 
    if (!hca_header) {
        // 分配内存失败的错误处理
    }

    // 获取PCIe能力寄存器的偏移量
    pcie_cap = pci_pcie_cap(dev->persist->pdev);

    // 备份当前的PCI配置头信息,忽略有特殊含义的配置偏移22和23
    for (i = 0; i < 64; ++i) {
        if (i == 22 || i == 23)
            continue;
        // 读PCI配置头信息到 hca_header 中
    }

    // 映射设备的重置寄存器地址
    reset = ioremap(pci_resource_start(dev->persist->pdev, 0) + MLX4_RESET_BASE, MLX4_RESET_SIZE);

    if (!reset) {
        // 重置寄存器映射失败处理
    }

    // 获取硬件信号量以防止在设备复位期间进行闪存更新
    end = jiffies + MLX4_SEM_TIMEOUT_JIFFIES;
    do {
        sem = readl(reset + MLX4_SEM_OFFSET);
        if (!sem)
            break;

        msleep(1);
    } while (time_before(jiffies, end));

    // sem仍然有效,则获取信号量失败
    if (sem) {
        // 获取信号量失败的错误处理
    }

    // 实际执行重置操作
    writel(MLX4_RESET_VALUE, reset + MLX4_RESET_OFFSET);

    // 释放重置寄存器的映射
    iounmap(reset);

    // 根据文档,重置后需要等待一秒钟再访问设备
    msleep(1000);

    // 等待设备复位完成并确认PCI设备可被访问
    end = jiffies + MLX4_RESET_TIMEOUT_JIFFIES;
    do {
        // 检查PCI_VENDOR_ID是否有效,如果有效,则设备复位成功
    } while (time_before(jiffies, end));

    // 如果vendor无效,代表设备复位失败
    if (vendor == 0xffff) {
        // 设备复位失败的错误处理
    }

    // 恢复之前保存的PCI配置头信息
    if (pcie_cap) {
        // 恢复PCIe设备控制和链接控制寄存器
    }

    // 恢复其他PCI配置头信息
    for (i = 0; i < 16; ++i) {
        // 写回PCI配置信息
    }

    // 最后,确保PCI_COMMAND寄存器被正确恢复
    if (pci_write_config_dword(dev->persist->pdev, PCI_COMMAND, hca_header[PCI_COMMAND / 4])) {
        // PCI_COMMAND寄存器恢复失败的错误处理
    }

out:
    // 释放之前分配的内存
    kfree(hca_header);

    return err;
}

这段代码涉及到硬件层面的操作,这其中包括了对PCI设备的配置空间的保存、设备重置以及恢复的过程。遵循Linux内核中的错误处理机制,使用goto语句跳转到错误处理代码段。通过互斥机制和延时确保操作的安全性。大部分详细的注释已经涵盖在代码里。

完整注释:

这段代码相对较长,将注释分成几部分进行讲解,每部分涵盖一个逻辑模块。

请注意:由于代码中使用了很多Linux内核特定的函数和宏定义,某些注释可能需要一定的内核知识才能完全理解。

//drivers\net\ethernet\mellanox\mlx4\reset.c
/*
 * 版权所有 (c) 2006, 2007 Cisco Systems, Inc. 保留所有权利。
 * 版权所有 (c) 2007, 2008 Mellanox Technologies. 保留所有权利。
 *
 * 这款软件可以在两种许可下的任何一种下提供给您。
 * 您可以选择被GNU通用公共许可证(GPL)版本2的条款所许可,
 * 可从该源代码树主目录中的COPYING文件中获取,
 * 或者选择下面的OpenIB.org BSD许可证:
 *
 *     源代码和二进制形式的再分发和使用是允许的,
 *     无论是否进行了修改,只要满足以下条件:
 *
 *      - 源代码的再分发必须保留上述版权声明、此条件列表和下面的免责声明。
 *
 *      - 以二进制形式进行的再分发必须在分发的文件和/或材料中复制上述版权声明、
 *        此条件列表以及随附的文件和/或材料中的免责声明。
 *
 * 本软件是按“原样”提供的,没有任何形式的保证,
 * 无论是明示的或暗示的,包括但不限于适销性、
 * 适用于特定用途的保证和非侵权。在任何情况下,
 * 作者或版权所有者均不对任何索赔、损害或其他责任承担责任,
 * 无论是在合同诉讼、侵权行为或其他方面,
 * 与本软件或本软件的使用或其他交易有关。
 */
// 引入一些必要的头文件
#include <linux/errno.h>    // 错误码定义
#include <linux/pci.h>      // PCI总线相关函数和结构体
#include <linux/delay.h>    // 延时相关的函数
#include <linux/slab.h>     // 内核内存分配相关
#include <linux/jiffies.h>  // 内核时间管理相关
#include "mlx4.h"           // Mellanox设备相关头文件
// 定义一个重置函数
int mlx4_reset(struct mlx4_dev *dev)
{
    void __iomem *reset;           // 映射设备寄存器的指针
    u32 *hca_header = NULL;        // 指向保存PCI头部数据的内存
    int pcie_cap;                  // PCI-E能力寄存器的位置
    u16 devctl, linkctl, vendor;   // 枚举一些PCI相关的变量
    unsigned long end;             // 用于记录超时时间
    u32 sem;                       // 记录半导体值
    int i;                         // 循环计数器
    int err = 0;                   // 错误码
    // 定义重置相关的常量
#define MLX4_RESET_BASE        0xf0000               // 重置寄存器的基础地址
#define MLX4_RESET_SIZE        0x400                 // 重置寄存器的大小
#define MLX4_SEM_OFFSET        0x3fc                 // 硬件信号量的偏移量
#define MLX4_RESET_OFFSET    0x10                  // 重置命令的偏移量
#define MLX4_RESET_VALUE    swab32(1)             // 重置命令的值
    // 定义超时的常数
#define MLX4_SEM_TIMEOUT_JIFFIES    (10 * HZ)  // 获取硬件信号量的超时时长
#define MLX4_RESET_TIMEOUT_JIFFIES    (2 * HZ)   // 重置等待超时的时长
    /*
     * 重置芯片。这个过程有点不优雅,因为我们必须在重置之前保存PCI头部,
     * 然后在芯片重启后恢复它。我们跳过配置空间偏移量22和23,因为它们有特殊含义。
     */
    // 是否需要保存完整的4K PCIe头?先分配空间以保存头部信息。
    hca_header = kmalloc(256, GFP_KERNEL);
    if (!hca_header) {
        err = -ENOMEM;  // 内存分配失败设置错误码
        mlx4_err(dev, "Couldn't allocate memory to save HCA PCI header, aborting\n");
        goto out;       // 跳转到函数的结束部分
    }
    // 获取PCI-E Capability的偏移量。
    pcie_cap = pci_pcie_cap(dev->persist->pdev);
    // 保存PCI配置空间的前256字节,跳过22和23偏移量的保存。
    for (i = 0; i < 64; ++i) {
        if (i == 22 || i == 23) 
            continue;
        // 读取PCI配置空间的每一个DWORD,并保存起来
        if (pci_read_config_dword(dev->persist->pdev, i * 4, hca_header + i)) {
            err = -ENODEV;  // 读取失败则设定错误码
            mlx4_err(dev, "Couldn't save HCA PCI header, aborting\n");
            goto out;
        }
    }

    // 映射重置寄存器的物理地址到虚拟地址空间
    reset = ioremap(pci_resource_start(dev->persist->pdev, 0) + MLX4_RESET_BASE, MLX4_RESET_SIZE);
    if (!reset) {
        err = -ENOMEM;  // 映射失败设置错误码
        mlx4_err(dev, "Couldn't map HCA reset register, aborting\n");
        goto out;
    }

    // 锁定硬件信号量,以阻止闪存更新
    end = jiffies + MLX4_SEM_TIMEOUT_JIFFIES;
    do {
        sem = readl(reset + MLX4_SEM_OFFSET);
        if (!sem)
            break;

        msleep(1);
    } while (time_before(jiffies, end));

    if (sem) {
        mlx4_err(dev, "Failed to obtain HW semaphore, aborting\n");
        err = -EAGAIN;  // 获取信号量失败设置错误码
        iounmap(reset);
        goto out;
    }

    // 实际进行重置操作
    writel(MLX4_RESET_VALUE, reset + MLX4_RESET_OFFSET);
    iounmap(reset);  // 解除映射

    // 文档指出在设备访问前等待一秒钟
    msleep(1000);

    // 等待设备复位完毕
    end = jiffies + MLX4_RESET_TIMEOUT_JIFFIES;
    do {
        if (!pci_read_config_word(dev->persist->pdev, PCI_VENDOR_ID, &vendor) && vendor != 0xffff)
            break;

        msleep(1);
    } while (time_before(jiffies, end));

    if (vendor == 0xffff) {
        err = -ENODEV;  // 设备重置后未恢复,则设置错误码
        mlx4_err(dev, "PCI device did not come back after reset, aborting\n");
        goto out;
    }

    // 恢复PCI头部信息
    if (pcie_cap) {
        devctl = hca_header[(pcie_cap + PCI_EXP_DEVCTL) / 4];
        if (pcie_capability_write_word(dev->persist->pdev, PCI_EXP_DEVCTL, devctl)) {
            err = -ENODEV;  // 恢复失败则设置错误码
            mlx4_err(dev, "Couldn't restore HCA PCI Express Device Control register, aborting\n");
            goto out;
        }
        linkctl = hca_header[(pcie_cap + PCI_EXP_LNKCTL) / 4];
        if (pcie_capability_write_word(dev->persist->pdev, PCI_EXP_LNKCTL, linkctl)) {
            err = -ENODEV;  // 恢复失败则设置错误码
            mlx4_err(dev, "Couldn't restore HCA PCI Express Link control register, aborting\n");
            goto out;
        }
    }

    for (i = 0; i < 16; ++i) {
        if (i * 4 == PCI_COMMAND)
            continue;

        if (pci_write_config_dword(dev->persist->pdev, i * 4, hca_header[i])) {
            err = -ENODEV;  // 写入失败则设置错误码
            mlx4_err(dev, "Couldn't restore HCA reg %x, aborting\n", i);
            goto out;
        }
    }

继续从最后一个`for`循环。

    // 最后恢复PCI_COMMAND寄存器。
    if (pci_write_config_dword(dev->persist->pdev, PCI_COMMAND, hca_header[PCI_COMMAND / 4])) {
        err = -ENODEV;  // 写入失败则设置错误码
        mlx4_err(dev, "Couldn't restore HCA COMMAND, aborting\n");
        goto out;
    }

out:
    kfree(hca_header);  // 释放之前保存PCI头部信息的内存空间

    return err;  // 返回错误码,0代表成功,非0代表失败
}

这部分代码主要执行了芯片的重置过程,并且在重置前后操作了PCI头部信息的保存与恢复,以确保设备能够在重置之后正常工作。需要注意的是代码中充满了错误检查和处理的步骤,以保证万一出现不可预见的问题时能够安全退出,并且反馈给调用者相应的错误信息。

二、讲解

这段代码来自Linux内核的Mellanox网络驱动mlx4,位于文件`reset.c`中。这个文件负责处理`mlx4`设备的重置逻辑。以下是代码中各个部分的中文解释:
代码开始于一个版权声明,声明代码属于Cisco Systems, Inc. 和 Mellanox Technologies所有,许可证可选为GPL(GNU通用公共许可证)版本2或OpenIB.org的BSD(伯克利软件许可证)。
接着引入了一些所需的Linux内核头文件。这些文件允许代码访问一些内核提供的功能,如内存分配和时间相关功能。
声明了`mlx4_reset`函数,它负责重置`mlx4_dev`指向的设备。
在函数中,定义了一些宏和它们的值:这些宏用于方便地引用重置流程中所需要的一些硬件寄存器的偏移量和相关的值。
函数`mlx4_reset`的实现分几个步骤:
1. 保存PCI配置头信息:在重置设备之前,需要保存PCI配置头的内容,以便后面可以恢复它。这是因为重置操作会导致这些信息丢失。作者注意到需要略过配置空间偏移量22和23,因为它们有特殊含义。
2. 映射重置寄存器:代码通过`ioremap`函数映射了设备的重置寄存器区域到内核地址空间,以便可以对它们进行读写操作。
3. 获取硬件信号量:在重置前需要获得一个硬件信号量,防止在重置时对闪存发生写操作。这里使用了循环,并通过读取信号量寄存器来判断是否获取成功。
4. 执行重置:通过向某个特定的寄存器写入特定值来触发硬件重置。
5. 等待设备初始化:硬件文档建议在访问设备之前等待一秒钟。
6. 恢复PCI头信息:重置完成后,PCI配置头信息需要从之前保存的内容恢复。
7. 清理:释放分配的内存空间,并返回执行结果。
整个函数的逻辑层次清晰,分为了准备、执行和清理三个主要部分。出错处理(错误标记`err`)也涵盖了各种可能的失败情况,例如内存分配失败、映射失败、信号量获取失败等,并在最后正确地释放资源和返回相应的错误代码。

ChatGPT

mlx4_reset是一种在InfiniBand驱动中遇到的函数,它一般是Mellanox InfiniBand驱动的一部分。这个函数用来将Mellanox InfiniBand硬件设备恢复到其初始状态。在Linux内核中,Mellanox的mlx4驱动负责管理InfiniBand设备。这个驱动通常与某些InfiniBand芯片组一起使用,比如那些被用在高性能计算集群中的芯片组。
由于InfiniBand驱动的代码是专业领域的内容,且通常需要深入了解硬件规格和内核编程,一个典型的`mlx4_reset`函数可能涉及复杂的硬件操作,包括直接与硬件交互的函数调用,内核同步机制,可能还有对硬件寄存器的读写。
在具体的C代码层面上,`mlx4_reset`函数的实现依赖于Mellanox硬件和驱动的具体版本,因此会根据不同的设备模型和驱动版本有所差异。但是,其大致框架可能如下所示:

int mlx4_reset(struct mlx4_dev *dev)
{
    // 获取设备上下文或设备特定的数据结构的引用
    struct mlx4_priv *priv = mlx4_priv(dev);

    // 执行硬件复位序列,可能包括:
    // - 禁用中断
    // - 停止设备端口
    // - 重置设备的某些区域或寄存器
    // - 将硬件状态置为已知的初始状态

    /* 示例代码,非真实代码 */
    mlx4_disable_interrupts(dev);
    mlx4_stop_device_ports(dev);
    
    // 实际的重置操作可以涉及对硬件寄存器的操作
    writel(value, priv->reset_reg); // 写入复位寄存器以重置设备

    // 检查设备是否已经重置完毕并且准备好重新初始化
    if (!mlx4_device_ready(dev)) {
        // 如果设备未能恢复到初始状态,则返回错误
        return -EIO;
    }

    // 重置成功后的操作,可能会重新初始化设备
    // 硬件复位后的设备必须重新初始化以便再次使用
    mlx4_enable_interrupts(dev);
    mlx4_start_device(dev);

    // 复位成功,返回0表示成功
    return 0;
}

请注意,上面的代码只是一个示意性的伪代码。实际的`mlx4_reset`函数包含更详细的步骤,包括对硬件规格的复杂操作,错误处理和设备状态的检查。要获得真实的源代码,您很可能需要访问Linux内核的源代码,具体到drivers/net/ethernet/mellanox/mlx4/目录中,您可以在该目录下找到与mlx4相关的实现。

通义灵码

在InfiniBand驱动程序中,mlx4_reset 函数通常用于复位 Mellanox InfiniBand Host Channel Adapter (HCA) 的硬件状态或某个特定功能模块。这个函数的作用是在遇到硬件错误、超时或其他需要恢复正常操作状态的情况时,重新初始化和同步HCA的硬件资源。

在C语言实现的Mellanox mlx4系列驱动中,mlx4_reset 函数可能执行如下步骤:

  1. 停止活动

    • 暂停所有正在进行的传输操作,包括清理发送和接收队列中的未完成请求(Work Requests, WRs)。
    • 中断任何正在使用的DMA传输。
  2. 硬件复位

    • 向HCA发送复位命令,使其进入已知初始状态。
    • 根据硬件规格书,通过相应的寄存器操作来触发和监控复位过程。
  3. 资源重置

    • 释放之前分配的硬件资源,如队列对、内存窗口、保护域等。
    • 重新初始化这些资源,确保它们处于有效可用的状态。
  4. 重新配置

    • 在硬件复位完成后,根据设备配置重新设置寄存器值和内部参数。
    • 重新建立硬件队列、中断处理机制和其他关键的硬件上下文。
  5. 启动服务

    • 重新启动必要的服务,比如恢复中断服务例程(Interrupt Service Routines, ISRs)。
    • 通知上层协议栈和应用程序复位已完成,可以继续进行新的通信操作。

请注意,上述流程是基于一般理解推测出的,具体实现细节会因不同版本的mlx4驱动而异,查看源代码是最准确的理解方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1557575.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

制造出海,灵途科技助力割草机器人、泳池清洁机器人全方位感知

近年来&#xff0c;越来越多的中国企业开始对外开拓&#xff0c;走向海外市场、挖掘和满足全球消费者的需求。在消费机器人领域&#xff0c;中国企业出海成绩亮眼&#xff01;在2024 ces 和上海AWE展会上&#xff0c;多家机器人公司展示了家用智能割草机器人、泳池清洁机器人的…

vue2 el-table指定某些数据不参与排序

vue2 el-table指定某些数据不参与排序 1、需求描述2、配置属性方法3、详细代码如下 1、需求描述 最后一行总计不参与排序 2、配置属性方法 el-table 需要配置 sort-change"soltHandle" 方法 el-table-column 需要配置 sortable"custom"属性3、详细代码如…

牛客周赛 Round 38(A,B,C,D,E,F,G)

比赛链接 官方讲解&#xff08;不分P不分段直接两小时怼上来是坏文明 &#xff09; 这场的题很棒&#xff0c;思维有难度&#xff0c;考察的知识点广泛&#xff0c;有深度&#xff0c;很透彻。感觉学到了很多。建议补题。 A 小红的正整数自增 思路&#xff1a; 签到。 可以…

uniapp开发微信小程序分包问题

现象 当我们开发完成小程序后&#xff0c;上传时&#xff0c;出现上传失败&#xff0c;此时就需要我们进行分包处理。 1.未分包之前 我们可以点击本地代码&#xff0c;进行查看 可以看到都是主包&#xff0c;表示没有进行分包处理。 2.在HBuilder X中点击源码视图 3.在mp-we…

rabbitMQ版本问题与下载

都到现在了&#xff0c;大家不会安装东西还是不看版本吧 云服务器买的是centos7&#xff0c;而erlang在24版本后不支持centos7了 所以需要找24版本以下的erlang&#xff0c;而不同erlang对应不同rabbitmq所以需要对应 下载erlang 说实话&#xff0c;自己安装&#xff0c;还是…

机器学习 - 创建多类别的数据

可以用到 scilit-learn 里的 make_blobs() 方法。这个方法用于生成聚类数据集&#xff0c;也用于测试和调试聚类算法。 import torch import matplotlib.pyplot as plt from sklearn.datasets import make_blobs from sklearn.model_selection import train_test_split NUM…

Mybatis-特殊SQL的执行

1. 模糊查询 在MyBatis中进行模糊查询时&#xff0c;有以下三种常见的实现方式&#xff1a; 1.1. 错误示范 先来个准备操作&#xff0c;并做一个错误示例 根据姓名&#xff0c;模糊查询用户&#xff0c;(x小x) 更新数据表 SQLMapper.java package com.sakurapaid.mybatis3…

pytest--python的一种测试框架--pytest初阶

前言 使用pytest去做测试时我们对文件名的命名其实是有规范的&#xff0c;要用test_开头&#xff01;&#xff01;&#xff01; 一、pytest初阶 def test_one():expect1actual1assert expectactual#测试专用语句&#xff1a;assert&#xff0c;识别期望与实际值是否相等这个…

Vue系列-el挂载

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>el:挂载点</title> </head> <body&g…

Mac上Matlab_R2023b ARM 版 启动闪退(意外退出)解决方法

安装好后&#xff0c;使用 "libmwlmgrimpl.dylib" 文件替换掉"/Applications/Matlab_R2023b.app/bin/maca64/matlab_startup_plugins/lmgrimpl"文件夹下的同名文件 在终端下执行如下命令&#xff1a; codesign --verbose --force --deep -s - /Applicat…

npm淘宝镜像源更新

目录 前情提要&#xff1a; 背景&#xff1a; 镜像源更新&#xff1a; 清楚缓存&#xff1a; 直接切换镜像源&#xff1a; 注&#xff1a;npm 补充&#xff1a; 错误解释&#xff1a; 解决方法&#xff1a; 前情提要&#xff1a; 2024 /1 /22 &#xff0c;registry.npm…

Python面对对象 - 类的反射机制

Python面对对象类的反射机制是面向对象编程语言中比较重要的功能&#xff0c;可以动态获取对象信息以及动态调用对象。通过字符串形式的类名或属性来访问对应类或属性。 一、对象的反射 1. getattr 获取指定字符串名称的对象属性、方法&#xff1a; 当访问的属性不存在时&#…

IPv6-重定向,PMTU,GRE隧道

IPv6-重定向&#xff0c;PMTU&#xff08;路径最大传输单元&#xff09;&#xff0c;GRE隧道&#xff08;Generic Routing Encapsulation&#xff0c;通用路由封装协议&#xff09; 重定向过程 触发重定向的条件&#xff1a; 1、报文的入接口&#xff0c;等于自身路由之后的…

深入理解SQLite:存储引擎、索引、事务与锁

文章目录 一、存储引擎二、索引的数据结构和类型2.1 B-Tree2.2 其他类型的索引2.3 小结 三、事务处理中的一致性问题3.1 脏读&#xff08;Dirty Read&#xff09;3.2 不可重复读&#xff08;Non-repeatable Read&#xff09;3.3 幻读&#xff08;Phantom Read&#xff09;3.4 小…

RVM安装Ruby笔记(Mac)

环境 硬件&#xff1a;Macbook Pro 系统&#xff1a;macOS 14.1 安装公钥 通过gpg安装公钥失败&#xff0c;报错如下&#xff1a; 换了几个公钥地址&#xff08;hkp://subkeys.pgp.net&#xff0c;hkp://keys.gnupg.net&#xff0c;hkp://pgp.mit.edu&#xff09;&#xff0c;…

mac怎么删除python

mac 默认安装了python2&#xff1b;自己后面又安装了python3&#xff1b;为了方便&#xff0c;现在想将python3换成Anaconda3。 Anaconda是一个开源的Python发行版本&#xff0c;其包含了conda、Python等180多个科学包及其依赖项。 Python3安装之后&#xff0c;在系统中不同目…

记录el-table的表格合并问题

项目需求背景&#xff1a; 利用el-table进行数据展示时&#xff0c;时常会有需要表格合并的情景&#xff0c;比如一个表格由5列组成&#xff1a; 类型 地区 金额 重量 长度 在这个表格里&#xff0c;如果同金额、重量的列可以合并到一起&#xff0c;这时应该怎么做呢&#xff1…

神经网络与深度学习(一)

线性回归 定义 利用数理统计中回归分析&#xff0c;来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法 要素 训练集&#xff08;训练数据&#xff09;输出数据拟合函数数据条目数 场景 预测价格&#xff08;房屋、股票等&#xff09;、预测住院时间&#…

计算机网络 - 基础篇总结

TCP/IP 网络模型有哪几层&#xff1f; 1.应用层 为用户提供应用功能 2.传输层 负责为应用层提供网络支持 使用TCP和UDP 当传输层的数据包大小超过 MSS&#xff08;TCP 最大报文段长度&#xff09; &#xff0c;就要将数据包分块&#xff0c;这样即使中途有一个分块丢失或损坏…

汇总:五个开源的Three.js项目

Three.js 是一个基于 WebGL 的 JavaScript 库&#xff0c;它提供了一套易于使用的 API 用来在浏览器中创建和显示 3D 图形。通过抽象和简化 WebGL 的复杂性&#xff0c;Three.js 使开发者无需深入了解 WebGL 的详细技术就能够轻松构建和渲染3D场景、模型、动画、粒子系统等。 T…